aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
committerDimitry Andric <dim@FreeBSD.org>2010-09-17 15:54:40 +0000
commit3d1dcd9bfdb15c49ee34d576a065079ac5c4d29f (patch)
tree0bbe07708f7571f8b5291f6d7b96c102b7c99dee /lib/Sema
parenta0482fa4e7fa27b01184f938097f0666b78016dd (diff)
downloadsrc-3d1dcd9bfdb15c49ee34d576a065079ac5c4d29f.tar.gz
src-3d1dcd9bfdb15c49ee34d576a065079ac5c4d29f.zip
Vendor import of clang r114020 (from the release_28 branch):vendor/clang/clang-r114020
Notes
Notes: svn path=/vendor/clang/dist/; revision=212795 svn path=/vendor/clang/clang-r114020/; revision=212796; tag=vendor/clang/clang-r114020
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp39
-rw-r--r--lib/Sema/AnalysisBasedWarnings.h55
-rw-r--r--lib/Sema/AttributeList.cpp136
-rw-r--r--lib/Sema/CMakeLists.txt3
-rw-r--r--lib/Sema/CXXFieldCollector.h79
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp233
-rw-r--r--lib/Sema/DeclSpec.cpp667
-rw-r--r--lib/Sema/IdentifierResolver.cpp35
-rw-r--r--lib/Sema/IdentifierResolver.h203
-rw-r--r--lib/Sema/JumpDiagnostics.cpp29
-rw-r--r--lib/Sema/Lookup.h654
-rw-r--r--lib/Sema/Makefile1
-rw-r--r--lib/Sema/ParseAST.cpp125
-rw-r--r--lib/Sema/Sema.cpp261
-rw-r--r--lib/Sema/Sema.h4655
-rw-r--r--lib/Sema/SemaAccess.cpp218
-rw-r--r--lib/Sema/SemaAttr.cpp135
-rw-r--r--lib/Sema/SemaCXXCast.cpp183
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp42
-rw-r--r--lib/Sema/SemaChecking.cpp870
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2077
-rw-r--r--lib/Sema/SemaDecl.cpp1400
-rw-r--r--lib/Sema/SemaDeclAttr.cpp453
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1068
-rw-r--r--lib/Sema/SemaDeclObjC.cpp442
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp10
-rw-r--r--lib/Sema/SemaExpr.cpp1704
-rw-r--r--lib/Sema/SemaExprCXX.cpp604
-rw-r--r--lib/Sema/SemaExprObjC.cpp136
-rw-r--r--lib/Sema/SemaInit.cpp383
-rw-r--r--lib/Sema/SemaInit.h765
-rw-r--r--lib/Sema/SemaLookup.cpp168
-rw-r--r--lib/Sema/SemaObjCProperty.cpp175
-rw-r--r--lib/Sema/SemaOverload.cpp1374
-rw-r--r--lib/Sema/SemaOverload.h617
-rw-r--r--lib/Sema/SemaStmt.cpp382
-rw-r--r--lib/Sema/SemaTemplate.cpp550
-rw-r--r--lib/Sema/SemaTemplate.h151
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp191
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp87
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp397
-rw-r--r--lib/Sema/SemaType.cpp154
-rw-r--r--lib/Sema/TargetAttributesSema.cpp17
-rw-r--r--lib/Sema/TargetAttributesSema.h2
-rw-r--r--lib/Sema/TreeTransform.h2028
45 files changed, 10189 insertions, 13769 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 448d16116a39..cfebed6a05b2 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -13,9 +13,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtObjC.h"
@@ -197,6 +199,8 @@ static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
return AlwaysFallThrough;
}
+namespace {
+
struct CheckFallThroughDiagnostics {
unsigned diag_MaybeFallThrough_HasNoReturn;
unsigned diag_MaybeFallThrough_ReturnsNonVoid;
@@ -266,6 +270,8 @@ struct CheckFallThroughDiagnostics {
}
};
+}
+
/// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
/// function that should return a value. Check that we don't fall off the end
/// of a noreturn function. We assume that functions and blocks not marked
@@ -375,19 +381,16 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
S.SourceMgr.isInSystemHeader(D->getLocation()))
return;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- // For function templates, class templates and member function templates
- // we'll do the analysis at instantiation time.
- if (FD->isDependentContext())
- return;
- }
+ // For code in dependent contexts, we'll do this at instantiation time.
+ if (cast<DeclContext>(D)->isDependentContext())
+ return;
const Stmt *Body = D->getBody();
assert(Body);
// Don't generate EH edges for CallExprs as we'd like to avoid the n^2
// explosion for destrutors that can result and the compile time hit.
- AnalysisContext AC(D, false);
+ AnalysisContext AC(D, 0, false);
// Warning: check missing 'return'
if (P.enableCheckFallThrough) {
@@ -401,3 +404,21 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
if (P.enableCheckUnreachable)
CheckUnreachable(S, AC);
}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+ const BlockExpr *E) {
+ return IssueWarnings(P, E->getBlockDecl(), E->getType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+ const ObjCMethodDecl *D) {
+ return IssueWarnings(P, D, QualType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+ const FunctionDecl *D) {
+ return IssueWarnings(P, D, QualType());
+}
diff --git a/lib/Sema/AnalysisBasedWarnings.h b/lib/Sema/AnalysisBasedWarnings.h
deleted file mode 100644
index dea19ba28ccf..000000000000
--- a/lib/Sema/AnalysisBasedWarnings.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines AnalysisBasedWarnings, a worker object used by Sema
-// that issues warnings based on dataflow-analysis.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
-#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class Sema;
-
-namespace sema {
-
-class AnalysisBasedWarnings {
-public:
- class Policy {
- friend class AnalysisBasedWarnings;
- // The warnings to run.
- unsigned enableCheckFallThrough : 1;
- unsigned enableCheckUnreachable : 1;
- public:
- Policy();
- void disableCheckFallThrough() { enableCheckFallThrough = 0; }
- };
-
-private:
- Sema &S;
- Policy DefaultPolicy;
-
- enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
- llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
-
-public:
- AnalysisBasedWarnings(Sema &s);
-
- Policy getDefaultPolicy() { return DefaultPolicy; }
-
- void IssueWarnings(Policy P, const Decl *D, QualType BlockTy = QualType());
-};
-
-}} // end namespace clang::sema
-
-#endif
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
new file mode 100644
index 000000000000..8ccb2ca586eb
--- /dev/null
+++ b/lib/Sema/AttributeList.cpp
@@ -0,0 +1,136 @@
+//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttributeList class implementation
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/AttributeList.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
+
+AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
+ IdentifierInfo *sName, SourceLocation sLoc,
+ IdentifierInfo *pName, SourceLocation pLoc,
+ Expr **ExprList, unsigned numArgs,
+ AttributeList *n, bool declspec, bool cxx0x)
+ : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
+ ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+ DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
+
+ if (numArgs == 0)
+ Args = 0;
+ else {
+ Args = new Expr*[numArgs];
+ memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
+ }
+}
+
+AttributeList::~AttributeList() {
+ if (Args) {
+ // FIXME: before we delete the vector, we need to make sure the Expr's
+ // have been deleted. Since ActionBase::ExprTy is "void", we are dependent
+ // on the actions module for actually freeing the memory. The specific
+ // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType,
+ // ParseField, ParseTag. Once these routines have freed the expression,
+ // they should zero out the Args slot (to indicate the memory has been
+ // freed). If any element of the vector is non-null, we should assert.
+ delete [] Args;
+ }
+ delete Next;
+}
+
+AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
+ llvm::StringRef AttrName = Name->getName();
+
+ // Normalize the attribute name, __foo__ becomes foo.
+ if (AttrName.startswith("__") && AttrName.endswith("__"))
+ AttrName = AttrName.substr(2, AttrName.size() - 4);
+
+ return llvm::StringSwitch<AttributeList::Kind>(AttrName)
+ .Case("weak", AT_weak)
+ .Case("weakref", AT_weakref)
+ .Case("pure", AT_pure)
+ .Case("mode", AT_mode)
+ .Case("used", AT_used)
+ .Case("alias", AT_alias)
+ .Case("align", AT_aligned)
+ .Case("final", AT_final)
+ .Case("cdecl", AT_cdecl)
+ .Case("const", AT_const)
+ .Case("blocks", AT_blocks)
+ .Case("format", AT_format)
+ .Case("hiding", AT_hiding)
+ .Case("malloc", AT_malloc)
+ .Case("packed", AT_packed)
+ .Case("unused", AT_unused)
+ .Case("aligned", AT_aligned)
+ .Case("cleanup", AT_cleanup)
+ .Case("nodebug", AT_nodebug)
+ .Case("nonnull", AT_nonnull)
+ .Case("nothrow", AT_nothrow)
+ .Case("objc_gc", AT_objc_gc)
+ .Case("regparm", AT_regparm)
+ .Case("section", AT_section)
+ .Case("stdcall", AT_stdcall)
+ .Case("annotate", AT_annotate)
+ .Case("fastcall", AT_fastcall)
+ .Case("ibaction", AT_IBAction)
+ .Case("iboutlet", AT_IBOutlet)
+ .Case("iboutletcollection", AT_IBOutletCollection)
+ .Case("noreturn", AT_noreturn)
+ .Case("noinline", AT_noinline)
+ .Case("override", AT_override)
+ .Case("sentinel", AT_sentinel)
+ .Case("NSObject", AT_nsobject)
+ .Case("dllimport", AT_dllimport)
+ .Case("dllexport", AT_dllexport)
+ .Case("may_alias", IgnoredAttribute) // FIXME: TBAA
+ .Case("base_check", AT_base_check)
+ .Case("deprecated", AT_deprecated)
+ .Case("visibility", AT_visibility)
+ .Case("destructor", AT_destructor)
+ .Case("format_arg", AT_format_arg)
+ .Case("gnu_inline", AT_gnu_inline)
+ .Case("weak_import", AT_weak_import)
+ .Case("vecreturn", AT_vecreturn)
+ .Case("vector_size", AT_vector_size)
+ .Case("constructor", AT_constructor)
+ .Case("unavailable", AT_unavailable)
+ .Case("overloadable", AT_overloadable)
+ .Case("address_space", AT_address_space)
+ .Case("always_inline", AT_always_inline)
+ .Case("returns_twice", IgnoredAttribute)
+ .Case("vec_type_hint", IgnoredAttribute)
+ .Case("objc_exception", AT_objc_exception)
+ .Case("ext_vector_type", AT_ext_vector_type)
+ .Case("transparent_union", AT_transparent_union)
+ .Case("analyzer_noreturn", AT_analyzer_noreturn)
+ .Case("warn_unused_result", AT_warn_unused_result)
+ .Case("carries_dependency", AT_carries_dependency)
+ .Case("ns_returns_not_retained", AT_ns_returns_not_retained)
+ .Case("ns_returns_retained", AT_ns_returns_retained)
+ .Case("cf_returns_not_retained", AT_cf_returns_not_retained)
+ .Case("cf_returns_retained", AT_cf_returns_retained)
+ .Case("ownership_returns", AT_ownership_returns)
+ .Case("ownership_holds", AT_ownership_holds)
+ .Case("ownership_takes", AT_ownership_takes)
+ .Case("reqd_work_group_size", AT_reqd_wg_size)
+ .Case("init_priority", AT_init_priority)
+ .Case("no_instrument_function", AT_no_instrument_function)
+ .Case("thiscall", AT_thiscall)
+ .Case("pascal", AT_pascal)
+ .Case("__cdecl", AT_cdecl)
+ .Case("__stdcall", AT_stdcall)
+ .Case("__fastcall", AT_fastcall)
+ .Case("__thiscall", AT_thiscall)
+ .Case("__pascal", AT_pascal)
+ .Default(UnknownAttribute);
+}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 70b4792f3ba5..e65bb227f159 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -2,10 +2,11 @@ set(LLVM_NO_RTTI 1)
add_clang_library(clangSema
AnalysisBasedWarnings.cpp
+ AttributeList.cpp
CodeCompleteConsumer.cpp
+ DeclSpec.cpp
IdentifierResolver.cpp
JumpDiagnostics.cpp
- ParseAST.cpp
Sema.cpp
SemaAccess.cpp
SemaAttr.cpp
diff --git a/lib/Sema/CXXFieldCollector.h b/lib/Sema/CXXFieldCollector.h
deleted file mode 100644
index 63c6ee3f74ba..000000000000
--- a/lib/Sema/CXXFieldCollector.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides CXXFieldCollector that is used during parsing & semantic
-// analysis of C++ classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class FieldDecl;
-
-/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
-/// C++ classes.
-class CXXFieldCollector {
- /// Fields - Contains all FieldDecls collected during parsing of a C++
- /// class. When a nested class is entered, its fields are appended to the
- /// fields of its parent class, when it is exited its fields are removed.
- llvm::SmallVector<FieldDecl*, 32> Fields;
-
- /// FieldCount - Each entry represents the number of fields collected during
- /// the parsing of a C++ class. When a nested class is entered, a new field
- /// count is pushed, when it is exited, the field count is popped.
- llvm::SmallVector<size_t, 4> FieldCount;
-
- // Example:
- //
- // class C {
- // int x,y;
- // class NC {
- // int q;
- // // At this point, Fields contains [x,y,q] decls and FieldCount contains
- // // [2,1].
- // };
- // int z;
- // // At this point, Fields contains [x,y,z] decls and FieldCount contains
- // // [3].
- // };
-
-public:
- /// StartClass - Called by Sema::ActOnStartCXXClassDef.
- void StartClass() { FieldCount.push_back(0); }
-
- /// Add - Called by Sema::ActOnCXXMemberDeclarator.
- void Add(FieldDecl *D) {
- Fields.push_back(D);
- ++FieldCount.back();
- }
-
- /// getCurNumField - The number of fields added to the currently parsed class.
- size_t getCurNumFields() const {
- assert(!FieldCount.empty() && "no currently-parsed class");
- return FieldCount.back();
- }
-
- /// getCurFields - Pointer to array of fields added to the currently parsed
- /// class.
- FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
-
- /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
- void FinishClass() {
- Fields.resize(Fields.size() - getCurNumFields());
- FieldCount.pop_back();
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 6cefc61f6640..58a1627b478a 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -11,11 +11,13 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Sema.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/Parse/Scope.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/Lex/Preprocessor.h"
#include "clang-c/Index.h"
-#include "Sema.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -234,8 +236,7 @@ std::string CodeCompletionString::getAsString() const {
default: OS << C->Text; break;
}
}
- OS.flush();
- return Result;
+ return OS.str();
}
const char *CodeCompletionString::getTypedText() const {
@@ -246,8 +247,10 @@ const char *CodeCompletionString::getTypedText() const {
return 0;
}
-CodeCompletionString *CodeCompletionString::Clone() const {
- CodeCompletionString *Result = new CodeCompletionString;
+CodeCompletionString *
+CodeCompletionString::Clone(CodeCompletionString *Result) const {
+ if (!Result)
+ Result = new CodeCompletionString;
for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
Result->AddChunk(C->Clone());
return Result;
@@ -373,19 +376,19 @@ bool CodeCompletionString::Deserialize(const char *&Str, const char *StrEnd) {
return true;
}
-void CodeCompleteConsumer::Result::Destroy() {
+void CodeCompletionResult::Destroy() {
if (Kind == RK_Pattern) {
delete Pattern;
Pattern = 0;
}
}
-unsigned CodeCompleteConsumer::Result::getPriorityFromDecl(NamedDecl *ND) {
+unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
if (!ND)
return CCP_Unlikely;
// Context-based decisions.
- DeclContext *DC = ND->getDeclContext()->getLookupContext();
+ DeclContext *DC = ND->getDeclContext()->getRedeclContext();
if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC))
return CCP_LocalDeclaration;
if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
@@ -437,13 +440,16 @@ CodeCompleteConsumer::~CodeCompleteConsumer() { }
void
PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
- Result *Results,
+ CodeCompletionContext Context,
+ CodeCompletionResult *Results,
unsigned NumResults) {
+ std::stable_sort(Results, Results + NumResults);
+
// Print the results.
for (unsigned I = 0; I != NumResults; ++I) {
OS << "COMPLETION: ";
switch (Results[I].Kind) {
- case Result::RK_Declaration:
+ case CodeCompletionResult::RK_Declaration:
OS << Results[I].Declaration;
if (Results[I].Hidden)
OS << " (Hidden)";
@@ -456,11 +462,11 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << '\n';
break;
- case Result::RK_Keyword:
+ case CodeCompletionResult::RK_Keyword:
OS << Results[I].Keyword << '\n';
break;
- case Result::RK_Macro: {
+ case CodeCompletionResult::RK_Macro: {
OS << Results[I].Macro->getName();
if (CodeCompletionString *CCS
= Results[I].CreateCodeCompletionString(SemaRef)) {
@@ -471,7 +477,7 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
break;
}
- case Result::RK_Pattern: {
+ case CodeCompletionResult::RK_Pattern: {
OS << "Pattern : "
<< Results[I].Pattern->getAsString() << '\n';
break;
@@ -494,116 +500,104 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
}
}
+void CodeCompletionResult::computeCursorKindAndAvailability() {
+ switch (Kind) {
+ case RK_Declaration:
+ // Set the availability based on attributes.
+ Availability = CXAvailability_Available;
+ if (Declaration->getAttr<UnavailableAttr>())
+ Availability = CXAvailability_NotAvailable;
+ else if (Declaration->getAttr<DeprecatedAttr>())
+ Availability = CXAvailability_Deprecated;
+
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
+ if (Function->isDeleted())
+ Availability = CXAvailability_NotAvailable;
+
+ CursorKind = getCursorKindForDecl(Declaration);
+ if (CursorKind == CXCursor_UnexposedDecl)
+ CursorKind = CXCursor_NotImplemented;
+ break;
+
+ case RK_Macro:
+ Availability = CXAvailability_Available;
+ CursorKind = CXCursor_MacroDefinition;
+ break;
+
+ case RK_Keyword:
+ Availability = CXAvailability_Available;
+ CursorKind = CXCursor_NotImplemented;
+ break;
+
+ case RK_Pattern:
+ // Do nothing: Patterns can come with cursor kinds!
+ break;
+ }
+}
+
+/// \brief Retrieve the name that should be used to order a result.
+///
+/// If the name needs to be constructed as a string, that string will be
+/// saved into Saved and the returned StringRef will refer to it.
+static llvm::StringRef getOrderedName(const CodeCompletionResult &R,
+ std::string &Saved) {
+ switch (R.Kind) {
+ case CodeCompletionResult::RK_Keyword:
+ return R.Keyword;
+
+ case CodeCompletionResult::RK_Pattern:
+ return R.Pattern->getTypedText();
+
+ case CodeCompletionResult::RK_Macro:
+ return R.Macro->getName();
+
+ case CodeCompletionResult::RK_Declaration:
+ // Handle declarations below.
+ break;
+ }
+
+ DeclarationName Name = R.Declaration->getDeclName();
+
+ // If the name is a simple identifier (by far the common case), or a
+ // zero-argument selector, just return a reference to that identifier.
+ if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
+ return Id->getName();
+ if (Name.isObjCZeroArgSelector())
+ if (IdentifierInfo *Id
+ = Name.getObjCSelector().getIdentifierInfoForSlot(0))
+ return Id->getName();
+
+ Saved = Name.getAsString();
+ return Saved;
+}
+
+bool clang::operator<(const CodeCompletionResult &X,
+ const CodeCompletionResult &Y) {
+ std::string XSaved, YSaved;
+ llvm::StringRef XStr = getOrderedName(X, XSaved);
+ llvm::StringRef YStr = getOrderedName(Y, YSaved);
+ int cmp = XStr.compare_lower(YStr);
+ if (cmp)
+ return cmp < 0;
+
+ // If case-insensitive comparison fails, try case-sensitive comparison.
+ cmp = XStr.compare(YStr);
+ if (cmp)
+ return cmp < 0;
+
+ return false;
+}
+
void
CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
- Result *Results,
+ CodeCompletionContext Context,
+ CodeCompletionResult *Results,
unsigned NumResults) {
// Print the results.
for (unsigned I = 0; I != NumResults; ++I) {
- CXCursorKind Kind = CXCursor_NotImplemented;
-
- switch (Results[I].Kind) {
- case Result::RK_Declaration:
- switch (Results[I].Declaration->getKind()) {
- case Decl::Record:
- case Decl::CXXRecord:
- case Decl::ClassTemplateSpecialization: {
- RecordDecl *Record = cast<RecordDecl>(Results[I].Declaration);
- if (Record->isStruct())
- Kind = CXCursor_StructDecl;
- else if (Record->isUnion())
- Kind = CXCursor_UnionDecl;
- else
- Kind = CXCursor_ClassDecl;
- break;
- }
-
- case Decl::ObjCMethod: {
- ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Results[I].Declaration);
- if (Method->isInstanceMethod())
- Kind = CXCursor_ObjCInstanceMethodDecl;
- else
- Kind = CXCursor_ObjCClassMethodDecl;
- break;
- }
-
- case Decl::Typedef:
- Kind = CXCursor_TypedefDecl;
- break;
-
- case Decl::Enum:
- Kind = CXCursor_EnumDecl;
- break;
-
- case Decl::Field:
- Kind = CXCursor_FieldDecl;
- break;
-
- case Decl::EnumConstant:
- Kind = CXCursor_EnumConstantDecl;
- break;
-
- case Decl::Function:
- case Decl::CXXMethod:
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- Kind = CXCursor_FunctionDecl;
- break;
-
- case Decl::Var:
- Kind = CXCursor_VarDecl;
- break;
-
- case Decl::ParmVar:
- Kind = CXCursor_ParmDecl;
- break;
-
- case Decl::ObjCInterface:
- Kind = CXCursor_ObjCInterfaceDecl;
- break;
-
- case Decl::ObjCCategory:
- Kind = CXCursor_ObjCCategoryDecl;
- break;
-
- case Decl::ObjCProtocol:
- Kind = CXCursor_ObjCProtocolDecl;
- break;
-
- case Decl::ObjCProperty:
- Kind = CXCursor_ObjCPropertyDecl;
- break;
-
- case Decl::ObjCIvar:
- Kind = CXCursor_ObjCIvarDecl;
- break;
-
- case Decl::ObjCImplementation:
- Kind = CXCursor_ObjCImplementationDecl;
- break;
-
- case Decl::ObjCCategoryImpl:
- Kind = CXCursor_ObjCCategoryImplDecl;
- break;
-
- default:
- break;
- }
- break;
-
- case Result::RK_Macro:
- Kind = CXCursor_MacroDefinition;
- break;
-
- case Result::RK_Keyword:
- case Result::RK_Pattern:
- Kind = CXCursor_NotImplemented;
- break;
- }
-
- WriteUnsigned(OS, Kind);
+ WriteUnsigned(OS, Results[I].CursorKind);
WriteUnsigned(OS, Results[I].Priority);
+ WriteUnsigned(OS, Results[I].Availability);
CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
assert(CCS && "No code-completion string?");
CCS->Serialize(OS);
@@ -618,7 +612,8 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
unsigned NumCandidates) {
for (unsigned I = 0; I != NumCandidates; ++I) {
WriteUnsigned(OS, CXCursor_NotImplemented);
- WriteUnsigned(OS, /*Priority=*/0);
+ WriteUnsigned(OS, /*Priority=*/I);
+ WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
CodeCompletionString *CCS
= Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
assert(CCS && "No code-completion string?");
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
new file mode 100644
index 000000000000..b46e8af9db86
--- /dev/null
+++ b/lib/Sema/DeclSpec.cpp
@@ -0,0 +1,667 @@
+//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements semantic analysis for declaration specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstring>
+using namespace clang;
+
+
+static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
+ SourceManager &SrcMgr, unsigned DiagID) {
+ return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
+}
+
+
+void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
+ assert(TemplateId && "NULL template-id annotation?");
+ Kind = IK_TemplateId;
+ this->TemplateId = TemplateId;
+ StartLocation = TemplateId->TemplateNameLoc;
+ EndLocation = TemplateId->RAngleLoc;
+}
+
+void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
+ assert(TemplateId && "NULL template-id annotation?");
+ Kind = IK_ConstructorTemplateId;
+ this->TemplateId = TemplateId;
+ StartLocation = TemplateId->TemplateNameLoc;
+ EndLocation = TemplateId->RAngleLoc;
+}
+
+/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+/// "TheDeclarator" is the declarator that this will be added to.
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+ SourceLocation EllipsisLoc,
+ ParamInfo *ArgInfo,
+ unsigned NumArgs,
+ unsigned TypeQuals,
+ bool hasExceptionSpec,
+ SourceLocation ThrowLoc,
+ bool hasAnyExceptionSpec,
+ ParsedType *Exceptions,
+ SourceRange *ExceptionRanges,
+ unsigned NumExceptions,
+ SourceLocation LPLoc,
+ SourceLocation RPLoc,
+ Declarator &TheDeclarator) {
+ DeclaratorChunk I;
+ I.Kind = Function;
+ I.Loc = LPLoc;
+ I.EndLoc = RPLoc;
+ I.Fun.hasPrototype = hasProto;
+ I.Fun.isVariadic = isVariadic;
+ I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
+ I.Fun.DeleteArgInfo = false;
+ I.Fun.TypeQuals = TypeQuals;
+ I.Fun.NumArgs = NumArgs;
+ I.Fun.ArgInfo = 0;
+ I.Fun.hasExceptionSpec = hasExceptionSpec;
+ I.Fun.ThrowLoc = ThrowLoc.getRawEncoding();
+ I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
+ I.Fun.NumExceptions = NumExceptions;
+ I.Fun.Exceptions = 0;
+
+ // new[] an argument array if needed.
+ if (NumArgs) {
+ // If the 'InlineParams' in Declarator is unused and big enough, put our
+ // parameter list there (in an effort to avoid new/delete traffic). If it
+ // is already used (consider a function returning a function pointer) or too
+ // small (function taking too many arguments), go to the heap.
+ if (!TheDeclarator.InlineParamsUsed &&
+ NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+ I.Fun.ArgInfo = TheDeclarator.InlineParams;
+ I.Fun.DeleteArgInfo = false;
+ TheDeclarator.InlineParamsUsed = true;
+ } else {
+ I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
+ I.Fun.DeleteArgInfo = true;
+ }
+ memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+ }
+ // new[] an exception array if needed
+ if (NumExceptions) {
+ I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
+ for (unsigned i = 0; i != NumExceptions; ++i) {
+ I.Fun.Exceptions[i].Ty = Exceptions[i];
+ I.Fun.Exceptions[i].Range = ExceptionRanges[i];
+ }
+ }
+ return I;
+}
+
+/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+/// declaration specifier includes.
+///
+unsigned DeclSpec::getParsedSpecifiers() const {
+ unsigned Res = 0;
+ if (StorageClassSpec != SCS_unspecified ||
+ SCS_thread_specified)
+ Res |= PQ_StorageClassSpecifier;
+
+ if (TypeQualifiers != TQ_unspecified)
+ Res |= PQ_TypeQualifier;
+
+ if (hasTypeSpecifier())
+ Res |= PQ_TypeSpecifier;
+
+ if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
+ Res |= PQ_FunctionSpecifier;
+ return Res;
+}
+
+template <class T> static bool BadSpecifier(T TNew, T TPrev,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ PrevSpec = DeclSpec::getSpecifierName(TPrev);
+ DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
+ : diag::err_invalid_decl_spec_combination);
+ return true;
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
+ switch (S) {
+ case DeclSpec::SCS_unspecified: return "unspecified";
+ case DeclSpec::SCS_typedef: return "typedef";
+ case DeclSpec::SCS_extern: return "extern";
+ case DeclSpec::SCS_static: return "static";
+ case DeclSpec::SCS_auto: return "auto";
+ case DeclSpec::SCS_register: return "register";
+ case DeclSpec::SCS_private_extern: return "__private_extern__";
+ case DeclSpec::SCS_mutable: return "mutable";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSW W) {
+ switch (W) {
+ case TSW_unspecified: return "unspecified";
+ case TSW_short: return "short";
+ case TSW_long: return "long";
+ case TSW_longlong: return "long long";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSC C) {
+ switch (C) {
+ case TSC_unspecified: return "unspecified";
+ case TSC_imaginary: return "imaginary";
+ case TSC_complex: return "complex";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+
+const char *DeclSpec::getSpecifierName(TSS S) {
+ switch (S) {
+ case TSS_unspecified: return "unspecified";
+ case TSS_signed: return "signed";
+ case TSS_unsigned: return "unsigned";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
+ switch (T) {
+ case DeclSpec::TST_unspecified: return "unspecified";
+ case DeclSpec::TST_void: return "void";
+ case DeclSpec::TST_char: return "char";
+ case DeclSpec::TST_wchar: return "wchar_t";
+ case DeclSpec::TST_char16: return "char16_t";
+ case DeclSpec::TST_char32: return "char32_t";
+ case DeclSpec::TST_int: return "int";
+ case DeclSpec::TST_float: return "float";
+ case DeclSpec::TST_double: return "double";
+ case DeclSpec::TST_bool: return "_Bool";
+ case DeclSpec::TST_decimal32: return "_Decimal32";
+ case DeclSpec::TST_decimal64: return "_Decimal64";
+ case DeclSpec::TST_decimal128: return "_Decimal128";
+ case DeclSpec::TST_enum: return "enum";
+ case DeclSpec::TST_class: return "class";
+ case DeclSpec::TST_union: return "union";
+ case DeclSpec::TST_struct: return "struct";
+ case DeclSpec::TST_typename: return "type-name";
+ case DeclSpec::TST_typeofType:
+ case DeclSpec::TST_typeofExpr: return "typeof";
+ case DeclSpec::TST_auto: return "auto";
+ case DeclSpec::TST_decltype: return "(decltype)";
+ case DeclSpec::TST_error: return "(error)";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TQ T) {
+ switch (T) {
+ case DeclSpec::TQ_unspecified: return "unspecified";
+ case DeclSpec::TQ_const: return "const";
+ case DeclSpec::TQ_restrict: return "restrict";
+ case DeclSpec::TQ_volatile: return "volatile";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
+bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (StorageClassSpec != SCS_unspecified) {
+ // Changing storage class is allowed only if the previous one
+ // was the 'extern' that is part of a linkage specification and
+ // the new storage class is 'typedef'.
+ if (!(SCS_extern_in_linkage_spec &&
+ StorageClassSpec == SCS_extern &&
+ S == SCS_typedef))
+ return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
+ }
+ StorageClassSpec = S;
+ StorageClassSpecLoc = Loc;
+ assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
+ return false;
+}
+
+bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (SCS_thread_specified) {
+ PrevSpec = "__thread";
+ DiagID = diag::ext_duplicate_declspec;
+ return true;
+ }
+ SCS_thread_specified = true;
+ SCS_threadLoc = Loc;
+ return false;
+}
+
+/// These methods set the specified attribute of the DeclSpec, but return true
+/// and ignore the request if invalid (e.g. "extern" then "auto" is
+/// specified).
+bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (TypeSpecWidth != TSW_unspecified &&
+ // Allow turning long -> long long.
+ (W != TSW_longlong || TypeSpecWidth != TSW_long))
+ return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
+ TypeSpecWidth = W;
+ TSWLoc = Loc;
+ if (TypeAltiVecVector && !TypeAltiVecBool &&
+ ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::warn_vector_long_decl_spec_combination;
+ return true;
+ }
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (TypeSpecComplex != TSC_unspecified)
+ return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
+ TypeSpecComplex = C;
+ TSCLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (TypeSpecSign != TSS_unspecified)
+ return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
+ TypeSpecSign = S;
+ TSSLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID,
+ ParsedType Rep) {
+ assert(isTypeRep(T) && "T does not store a type");
+ assert(Rep && "no type provided!");
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_decl_spec_combination;
+ return true;
+ }
+ TypeSpecType = T;
+ TypeRep = Rep;
+ TSTLoc = Loc;
+ TypeSpecOwned = false;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID,
+ Expr *Rep) {
+ assert(isExprRep(T) && "T does not store an expr");
+ assert(Rep && "no expression provided!");
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_decl_spec_combination;
+ return true;
+ }
+ TypeSpecType = T;
+ ExprRep = Rep;
+ TSTLoc = Loc;
+ TypeSpecOwned = false;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID,
+ Decl *Rep, bool Owned) {
+ assert(isDeclRep(T) && "T does not store a decl");
+ // Unlike the other cases, we don't assert that we actually get a decl.
+
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_decl_spec_combination;
+ return true;
+ }
+ TypeSpecType = T;
+ DeclRep = Rep;
+ TSTLoc = Loc;
+ TypeSpecOwned = Owned;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+ const char *&PrevSpec,
+ unsigned &DiagID) {
+ assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
+ "rep required for these type-spec kinds!");
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_decl_spec_combination;
+ return true;
+ }
+ if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
+ TypeAltiVecBool = true;
+ TSTLoc = Loc;
+ return false;
+ }
+ TypeSpecType = T;
+ TSTLoc = Loc;
+ TypeSpecOwned = false;
+ if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_vector_decl_spec;
+ return true;
+ }
+ return false;
+}
+
+bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_vector_decl_spec_combination;
+ return true;
+ }
+ TypeAltiVecVector = isAltiVecVector;
+ AltiVecLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (!TypeAltiVecVector || TypeAltiVecPixel ||
+ (TypeSpecType != TST_unspecified)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_pixel_decl_spec_combination;
+ return true;
+ }
+ TypeAltiVecPixel = isAltiVecPixel;
+ TSTLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetTypeSpecError() {
+ TypeSpecType = TST_error;
+ TypeSpecOwned = false;
+ TSTLoc = SourceLocation();
+ return false;
+}
+
+bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID, const LangOptions &Lang) {
+ // Duplicates turn into warnings pre-C99.
+ if ((TypeQualifiers & T) && !Lang.C99)
+ return BadSpecifier(T, T, PrevSpec, DiagID);
+ TypeQualifiers |= T;
+
+ switch (T) {
+ default: assert(0 && "Unknown type qualifier!");
+ case TQ_const: TQ_constLoc = Loc; break;
+ case TQ_restrict: TQ_restrictLoc = Loc; break;
+ case TQ_volatile: TQ_volatileLoc = Loc; break;
+ }
+ return false;
+}
+
+bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ // 'inline inline' is ok.
+ FS_inline_specified = true;
+ FS_inlineLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ // 'virtual virtual' is ok.
+ FS_virtual_specified = true;
+ FS_virtualLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ // 'explicit explicit' is ok.
+ FS_explicit_specified = true;
+ FS_explicitLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ if (Friend_specified) {
+ PrevSpec = "friend";
+ DiagID = diag::ext_duplicate_declspec;
+ return true;
+ }
+
+ Friend_specified = true;
+ FriendLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+ unsigned &DiagID) {
+ // 'constexpr constexpr' is ok.
+ Constexpr_specified = true;
+ ConstexprLoc = Loc;
+ return false;
+}
+
+void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
+ unsigned NP,
+ SourceLocation *ProtoLocs,
+ SourceLocation LAngleLoc) {
+ if (NP == 0) return;
+ ProtocolQualifiers = new Decl*[NP];
+ ProtocolLocs = new SourceLocation[NP];
+ memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
+ memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
+ NumProtocolQualifiers = NP;
+ ProtocolLAngleLoc = LAngleLoc;
+}
+
+void DeclSpec::SaveWrittenBuiltinSpecs() {
+ writtenBS.Sign = getTypeSpecSign();
+ writtenBS.Width = getTypeSpecWidth();
+ writtenBS.Type = getTypeSpecType();
+ // Search the list of attributes for the presence of a mode attribute.
+ writtenBS.ModeAttr = false;
+ AttributeList* attrs = getAttributes();
+ while (attrs) {
+ if (attrs->getKind() == AttributeList::AT_mode) {
+ writtenBS.ModeAttr = true;
+ break;
+ }
+ attrs = attrs->getNext();
+ }
+}
+
+void DeclSpec::SaveStorageSpecifierAsWritten() {
+ if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
+ // If 'extern' is part of a linkage specification,
+ // then it is not a storage class "as written".
+ StorageClassSpecAsWritten = SCS_unspecified;
+ else
+ StorageClassSpecAsWritten = StorageClassSpec;
+}
+
+/// Finish - This does final analysis of the declspec, rejecting things like
+/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
+/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
+/// DeclSpec is guaranteed self-consistent, even if an error occurred.
+void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
+ // Before possibly changing their values, save specs as written.
+ SaveWrittenBuiltinSpecs();
+ SaveStorageSpecifierAsWritten();
+
+ // Check the type specifier components first.
+ SourceManager &SrcMgr = PP.getSourceManager();
+
+ // Validate and finalize AltiVec vector declspec.
+ if (TypeAltiVecVector) {
+ if (TypeAltiVecBool) {
+ // Sign specifiers are not allowed with vector bool. (PIM 2.1)
+ if (TypeSpecSign != TSS_unspecified) {
+ Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << getSpecifierName((TSS)TypeSpecSign);
+ }
+
+ // Only char/int are valid with vector bool. (PIM 2.1)
+ if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
+ (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
+ Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << (TypeAltiVecPixel ? "__pixel" :
+ getSpecifierName((TST)TypeSpecType));
+ }
+
+ // Only 'short' is valid with vector bool. (PIM 2.1)
+ if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
+ Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+ << getSpecifierName((TSW)TypeSpecWidth);
+
+ // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
+ if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
+ (TypeSpecWidth != TSW_unspecified))
+ TypeSpecSign = TSS_unsigned;
+ }
+
+ if (TypeAltiVecPixel) {
+ //TODO: perform validation
+ TypeSpecType = TST_int;
+ TypeSpecSign = TSS_unsigned;
+ TypeSpecWidth = TSW_short;
+ TypeSpecOwned = false;
+ }
+ }
+
+ // signed/unsigned are only valid with int/char/wchar_t.
+ if (TypeSpecSign != TSS_unspecified) {
+ if (TypeSpecType == TST_unspecified)
+ TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
+ else if (TypeSpecType != TST_int &&
+ TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
+ Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
+ << getSpecifierName((TST)TypeSpecType);
+ // signed double -> double.
+ TypeSpecSign = TSS_unspecified;
+ }
+ }
+
+ // Validate the width of the type.
+ switch (TypeSpecWidth) {
+ case TSW_unspecified: break;
+ case TSW_short: // short int
+ case TSW_longlong: // long long int
+ if (TypeSpecType == TST_unspecified)
+ TypeSpecType = TST_int; // short -> short int, long long -> long long int.
+ else if (TypeSpecType != TST_int) {
+ Diag(D, TSWLoc, SrcMgr,
+ TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
+ : diag::err_invalid_longlong_spec)
+ << getSpecifierName((TST)TypeSpecType);
+ TypeSpecType = TST_int;
+ TypeSpecOwned = false;
+ }
+ break;
+ case TSW_long: // long double, long int
+ if (TypeSpecType == TST_unspecified)
+ TypeSpecType = TST_int; // long -> long int.
+ else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
+ Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
+ << getSpecifierName((TST)TypeSpecType);
+ TypeSpecType = TST_int;
+ TypeSpecOwned = false;
+ }
+ break;
+ }
+
+ // TODO: if the implementation does not implement _Complex or _Imaginary,
+ // disallow their use. Need information about the backend.
+ if (TypeSpecComplex != TSC_unspecified) {
+ if (TypeSpecType == TST_unspecified) {
+ Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
+ << FixItHint::CreateInsertion(
+ PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
+ " double");
+ TypeSpecType = TST_double; // _Complex -> _Complex double.
+ } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
+ // Note that this intentionally doesn't include _Complex _Bool.
+ Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
+ } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
+ Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
+ << getSpecifierName((TST)TypeSpecType);
+ TypeSpecComplex = TSC_unspecified;
+ }
+ }
+
+ // C++ [class.friend]p6:
+ // No storage-class-specifier shall appear in the decl-specifier-seq
+ // of a friend declaration.
+ if (isFriendSpecified() && getStorageClassSpec()) {
+ DeclSpec::SCS SC = getStorageClassSpec();
+ const char *SpecName = getSpecifierName(SC);
+
+ SourceLocation SCLoc = getStorageClassSpecLoc();
+ SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
+
+ Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
+ << SpecName
+ << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
+
+ ClearStorageClassSpecs();
+ }
+
+ assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
+
+ // Okay, now we can infer the real type.
+
+ // TODO: return "auto function" and other bad things based on the real type.
+
+ // 'data definition has no type or storage class'?
+}
+
+bool DeclSpec::isMissingDeclaratorOk() {
+ TST tst = getTypeSpecType();
+ return isDeclRep(tst) && getRepAsDecl() != 0 &&
+ StorageClassSpec != DeclSpec::SCS_typedef;
+}
+
+void UnqualifiedId::clear() {
+ if (Kind == IK_TemplateId)
+ TemplateId->Destroy();
+
+ Kind = IK_Identifier;
+ Identifier = 0;
+ StartLocation = SourceLocation();
+ EndLocation = SourceLocation();
+}
+
+void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
+ OverloadedOperatorKind Op,
+ SourceLocation SymbolLocations[3]) {
+ Kind = IK_OperatorFunctionId;
+ StartLocation = OperatorLoc;
+ EndLocation = OperatorLoc;
+ OperatorFunctionId.Operator = Op;
+ for (unsigned I = 0; I != 3; ++I) {
+ OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
+
+ if (SymbolLocations[I].isValid())
+ EndLocation = SymbolLocations[I];
+ }
+}
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index b09526e097b6..3f16ed772352 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -12,7 +12,9 @@
//
//===----------------------------------------------------------------------===//
-#include "IdentifierResolver.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/Scope.h"
+#include "clang/AST/Decl.h"
#include "clang/Basic/LangOptions.h"
using namespace clang;
@@ -103,7 +105,7 @@ IdentifierResolver::~IdentifierResolver() {
/// true if 'D' belongs to the given declaration context.
bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
ASTContext &Context, Scope *S) const {
- Ctx = Ctx->getLookupContext();
+ Ctx = Ctx->getRedeclContext();
if (Ctx->isFunctionOrMethod()) {
// Ignore the scopes associated within transparent declaration contexts.
@@ -111,7 +113,7 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
((DeclContext *)S->getEntity())->isTransparentContext())
S = S->getParent();
- if (S->isDeclScope(Action::DeclPtrTy::make(D)))
+ if (S->isDeclScope(D))
return true;
if (LangOpt.CPlusPlus) {
// C++ 3.3.2p3:
@@ -128,17 +130,20 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
//
assert(S->getParent() && "No TUScope?");
if (S->getParent()->getFlags() & Scope::ControlScope)
- return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
+ return S->getParent()->isDeclScope(D);
}
return false;
}
- return D->getDeclContext()->getLookupContext()->Equals(Ctx);
+ return D->getDeclContext()->getRedeclContext()->Equals(Ctx);
}
/// AddDecl - Link the decl to its shadowed decl chain.
void IdentifierResolver::AddDecl(NamedDecl *D) {
DeclarationName Name = D->getDeclName();
+ if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+ II->setIsFromAST(false);
+
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
@@ -164,6 +169,9 @@ void IdentifierResolver::AddDecl(NamedDecl *D) {
void IdentifierResolver::RemoveDecl(NamedDecl *D) {
assert(D && "null param passed");
DeclarationName Name = D->getDeclName();
+ if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+ II->setIsFromAST(false);
+
void *Ptr = Name.getFETokenInfo<void>();
assert(Ptr && "Didn't find this decl on its identifier's chain!");
@@ -182,6 +190,9 @@ bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
"Cannot replace a decl with another decl of a different name");
DeclarationName Name = Old->getDeclName();
+ if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+ II->setIsFromAST(false);
+
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr)
@@ -218,6 +229,7 @@ IdentifierResolver::begin(DeclarationName Name) {
void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
NamedDecl *D) {
+ II->setIsFromAST(false);
void *Ptr = II->getFETokenInfo<void>();
if (!Ptr) {
@@ -261,3 +273,16 @@ IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
++CurIndex;
return *IDI;
}
+
+void IdentifierResolver::iterator::incrementSlowCase() {
+ NamedDecl *D = **this;
+ void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
+ assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
+ IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
+
+ BaseIter I = getIterator();
+ if (I != Info->decls_begin())
+ *this = iterator(I-1);
+ else // No more decls.
+ *this = iterator();
+}
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
deleted file mode 100644
index 59bd834073f3..000000000000
--- a/lib/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the IdentifierResolver class, which is used for lexical
-// scoped lookup, based on declaration names.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Parse/Scope.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/DeclCXX.h"
-
-namespace clang {
-
-/// IdentifierResolver - Keeps track of shadowed decls on enclosing
-/// scopes. It manages the shadowing chains of declaration names and
-/// implements efficent decl lookup based on a declaration name.
-class IdentifierResolver {
-
- /// IdDeclInfo - Keeps track of information about decls associated
- /// to a particular declaration name. IdDeclInfos are lazily
- /// constructed and assigned to a declaration name the first time a
- /// decl with that declaration name is shadowed in some scope.
- class IdDeclInfo {
- public:
- typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
-
- inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
- inline DeclsTy::iterator decls_end() { return Decls.end(); }
-
- void AddDecl(NamedDecl *D) { Decls.push_back(D); }
-
- /// RemoveDecl - Remove the decl from the scope chain.
- /// The decl must already be part of the decl chain.
- void RemoveDecl(NamedDecl *D);
-
- /// Replaces the Old declaration with the New declaration. If the
- /// replacement is successful, returns true. If the old
- /// declaration was not found, returns false.
- bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
-
- private:
- DeclsTy Decls;
- };
-
-public:
-
- /// iterator - Iterate over the decls of a specified declaration name.
- /// It will walk or not the parent declaration contexts depending on how
- /// it was instantiated.
- class iterator {
- public:
- typedef NamedDecl * value_type;
- typedef NamedDecl * reference;
- typedef NamedDecl * pointer;
- typedef std::input_iterator_tag iterator_category;
- typedef std::ptrdiff_t difference_type;
-
- /// Ptr - There are 3 forms that 'Ptr' represents:
- /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
- /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
- /// same declaration context. (Ptr & 0x3 == 0x1)
- /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
- /// declaration contexts too. (Ptr & 0x3 == 0x3)
- uintptr_t Ptr;
- typedef IdDeclInfo::DeclsTy::iterator BaseIter;
-
- /// A single NamedDecl. (Ptr & 0x1 == 0)
- iterator(NamedDecl *D) {
- Ptr = reinterpret_cast<uintptr_t>(D);
- assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
- }
- /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
- /// contexts depending on 'LookInParentCtx'.
- iterator(BaseIter I) {
- Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
- }
-
- bool isIterator() const { return (Ptr & 0x1); }
-
- BaseIter getIterator() const {
- assert(isIterator() && "Ptr not an iterator!");
- return reinterpret_cast<BaseIter>(Ptr & ~0x3);
- }
-
- friend class IdentifierResolver;
- public:
- iterator() : Ptr(0) {}
-
- NamedDecl *operator*() const {
- if (isIterator())
- return *getIterator();
- else
- return reinterpret_cast<NamedDecl*>(Ptr);
- }
-
- bool operator==(const iterator &RHS) const {
- return Ptr == RHS.Ptr;
- }
- bool operator!=(const iterator &RHS) const {
- return Ptr != RHS.Ptr;
- }
-
- // Preincrement.
- iterator& operator++() {
- if (!isIterator()) // common case.
- Ptr = 0;
- else {
- NamedDecl *D = **this;
- void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
- assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
- IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
-
- BaseIter I = getIterator();
- if (I != Info->decls_begin())
- *this = iterator(I-1);
- else // No more decls.
- *this = iterator();
- }
- return *this;
- }
-
- uintptr_t getAsOpaqueValue() const { return Ptr; }
-
- static iterator getFromOpaqueValue(uintptr_t P) {
- iterator Result;
- Result.Ptr = P;
- return Result;
- }
- };
-
- /// begin - Returns an iterator for decls with the name 'Name'.
- static iterator begin(DeclarationName Name);
-
- /// end - Returns an iterator that has 'finished'.
- static iterator end() {
- return iterator();
- }
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
- Scope *S = 0) const;
-
- /// AddDecl - Link the decl to its shadowed decl chain.
- void AddDecl(NamedDecl *D);
-
- /// RemoveDecl - Unlink the decl from its shadowed decl chain.
- /// The decl must already be part of the decl chain.
- void RemoveDecl(NamedDecl *D);
-
- /// Replace the decl Old with the new declaration New on its
- /// identifier chain. Returns true if the old declaration was found
- /// (and, therefore, replaced).
- bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
-
- /// \brief Link the declaration into the chain of declarations for
- /// the given identifier.
- ///
- /// This is a lower-level routine used by the PCH reader to link a
- /// declaration into a specific IdentifierInfo before the
- /// declaration actually has a name.
- void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D);
-
- explicit IdentifierResolver(const LangOptions &LangOpt);
- ~IdentifierResolver();
-
-private:
- const LangOptions &LangOpt;
-
- class IdDeclInfoMap;
- IdDeclInfoMap *IdDeclInfos;
-
- /// FETokenInfo contains a Decl pointer if lower bit == 0.
- static inline bool isDeclPtr(void *Ptr) {
- return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
- }
-
- /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
- static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
- assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
- && "Ptr not a IdDeclInfo* !");
- return reinterpret_cast<IdDeclInfo*>(
- reinterpret_cast<uintptr_t>(Ptr) & ~0x1
- );
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 3431ac611886..b23f615af7b7 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/BitVector.h"
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtCXX.h"
+#include "llvm/ADT/BitVector.h"
using namespace clang;
namespace {
@@ -180,12 +181,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
// If we found a label, remember that it is in ParentScope scope.
switch (S->getStmtClass()) {
- case Stmt::LabelStmtClass:
- case Stmt::DefaultStmtClass:
- case Stmt::CaseStmtClass:
- LabelAndGotoScopes[S] = ParentScope;
- break;
-
case Stmt::AddrLabelExprClass:
IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
break;
@@ -225,6 +220,24 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
Stmt *SubStmt = *CI;
if (SubStmt == 0) continue;
+ // Cases, labels, and defaults aren't "scope parents". It's also
+ // important to handle these iteratively instead of recursively in
+ // order to avoid blowing out the stack.
+ while (true) {
+ Stmt *Next;
+ if (isa<CaseStmt>(SubStmt))
+ Next = cast<CaseStmt>(SubStmt)->getSubStmt();
+ else if (isa<DefaultStmt>(SubStmt))
+ Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
+ else if (isa<LabelStmt>(SubStmt))
+ Next = cast<LabelStmt>(SubStmt)->getSubStmt();
+ else
+ break;
+
+ LabelAndGotoScopes[SubStmt] = ParentScope;
+ SubStmt = Next;
+ }
+
// If this is a declstmt with a VLA definition, it defines a scope from here
// to the end of the containing context.
if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
deleted file mode 100644
index 271bb5bcd4a7..000000000000
--- a/lib/Sema/Lookup.h
+++ /dev/null
@@ -1,654 +0,0 @@
-//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the LookupResult class, which is integral to
-// Sema's name-lookup subsystem.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_LOOKUP_H
-#define LLVM_CLANG_SEMA_LOOKUP_H
-
-#include "Sema.h"
-
-namespace clang {
-
-/// @brief Represents the results of name lookup.
-///
-/// An instance of the LookupResult class captures the results of a
-/// single name lookup, which can return no result (nothing found),
-/// a single declaration, a set of overloaded functions, or an
-/// ambiguity. Use the getKind() method to determine which of these
-/// results occurred for a given lookup.
-class LookupResult {
-public:
- enum LookupResultKind {
- /// @brief No entity found met the criteria.
- NotFound = 0,
-
- /// @brief No entity found met the criteria within the current
- /// instantiation,, but there were dependent base classes of the
- /// current instantiation that could not be searched.
- NotFoundInCurrentInstantiation,
-
- /// @brief Name lookup found a single declaration that met the
- /// criteria. getFoundDecl() will return this declaration.
- Found,
-
- /// @brief Name lookup found a set of overloaded functions that
- /// met the criteria.
- FoundOverloaded,
-
- /// @brief Name lookup found an unresolvable value declaration
- /// and cannot yet complete. This only happens in C++ dependent
- /// contexts with dependent using declarations.
- FoundUnresolvedValue,
-
- /// @brief Name lookup results in an ambiguity; use
- /// getAmbiguityKind to figure out what kind of ambiguity
- /// we have.
- Ambiguous
- };
-
- enum AmbiguityKind {
- /// Name lookup results in an ambiguity because multiple
- /// entities that meet the lookup criteria were found in
- /// subobjects of different types. For example:
- /// @code
- /// struct A { void f(int); }
- /// struct B { void f(double); }
- /// struct C : A, B { };
- /// void test(C c) {
- /// c.f(0); // error: A::f and B::f come from subobjects of different
- /// // types. overload resolution is not performed.
- /// }
- /// @endcode
- AmbiguousBaseSubobjectTypes,
-
- /// Name lookup results in an ambiguity because multiple
- /// nonstatic entities that meet the lookup criteria were found
- /// in different subobjects of the same type. For example:
- /// @code
- /// struct A { int x; };
- /// struct B : A { };
- /// struct C : A { };
- /// struct D : B, C { };
- /// int test(D d) {
- /// return d.x; // error: 'x' is found in two A subobjects (of B and C)
- /// }
- /// @endcode
- AmbiguousBaseSubobjects,
-
- /// Name lookup results in an ambiguity because multiple definitions
- /// of entity that meet the lookup criteria were found in different
- /// declaration contexts.
- /// @code
- /// namespace A {
- /// int i;
- /// namespace B { int i; }
- /// int test() {
- /// using namespace B;
- /// return i; // error 'i' is found in namespace A and A::B
- /// }
- /// }
- /// @endcode
- AmbiguousReference,
-
- /// Name lookup results in an ambiguity because an entity with a
- /// tag name was hidden by an entity with an ordinary name from
- /// a different context.
- /// @code
- /// namespace A { struct Foo {}; }
- /// namespace B { void Foo(); }
- /// namespace C {
- /// using namespace A;
- /// using namespace B;
- /// }
- /// void test() {
- /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
- /// // different namespace
- /// }
- /// @endcode
- AmbiguousTagHiding
- };
-
- /// A little identifier for flagging temporary lookup results.
- enum TemporaryToken {
- Temporary
- };
-
- typedef UnresolvedSetImpl::iterator iterator;
-
- LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
- Sema::LookupNameKind LookupKind,
- Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
- : ResultKind(NotFound),
- Paths(0),
- NamingClass(0),
- SemaRef(SemaRef),
- Name(Name),
- NameLoc(NameLoc),
- LookupKind(LookupKind),
- IDNS(0),
- Redecl(Redecl != Sema::NotForRedeclaration),
- HideTags(true),
- Diagnose(Redecl == Sema::NotForRedeclaration)
- {
- configure();
- }
-
- /// Creates a temporary lookup result, initializing its core data
- /// using the information from another result. Diagnostics are always
- /// disabled.
- LookupResult(TemporaryToken _, const LookupResult &Other)
- : ResultKind(NotFound),
- Paths(0),
- NamingClass(0),
- SemaRef(Other.SemaRef),
- Name(Other.Name),
- NameLoc(Other.NameLoc),
- LookupKind(Other.LookupKind),
- IDNS(Other.IDNS),
- Redecl(Other.Redecl),
- HideTags(Other.HideTags),
- Diagnose(false)
- {}
-
- ~LookupResult() {
- if (Diagnose) diagnose();
- if (Paths) deletePaths(Paths);
- }
-
- /// Gets the name to look up.
- DeclarationName getLookupName() const {
- return Name;
- }
-
- /// \brief Sets the name to look up.
- void setLookupName(DeclarationName Name) {
- this->Name = Name;
- }
-
- /// Gets the kind of lookup to perform.
- Sema::LookupNameKind getLookupKind() const {
- return LookupKind;
- }
-
- /// True if this lookup is just looking for an existing declaration.
- bool isForRedeclaration() const {
- return Redecl;
- }
-
- /// Sets whether tag declarations should be hidden by non-tag
- /// declarations during resolution. The default is true.
- void setHideTags(bool Hide) {
- HideTags = Hide;
- }
-
- bool isAmbiguous() const {
- return getResultKind() == Ambiguous;
- }
-
- /// Determines if this names a single result which is not an
- /// unresolved value using decl. If so, it is safe to call
- /// getFoundDecl().
- bool isSingleResult() const {
- return getResultKind() == Found;
- }
-
- /// Determines if the results are overloaded.
- bool isOverloadedResult() const {
- return getResultKind() == FoundOverloaded;
- }
-
- bool isUnresolvableResult() const {
- return getResultKind() == FoundUnresolvedValue;
- }
-
- LookupResultKind getResultKind() const {
- sanity();
- return ResultKind;
- }
-
- AmbiguityKind getAmbiguityKind() const {
- assert(isAmbiguous());
- return Ambiguity;
- }
-
- const UnresolvedSetImpl &asUnresolvedSet() const {
- return Decls;
- }
-
- iterator begin() const { return iterator(Decls.begin()); }
- iterator end() const { return iterator(Decls.end()); }
-
- /// \brief Return true if no decls were found
- bool empty() const { return Decls.empty(); }
-
- /// \brief Return the base paths structure that's associated with
- /// these results, or null if none is.
- CXXBasePaths *getBasePaths() const {
- return Paths;
- }
-
- /// \brief Tests whether the given declaration is acceptable.
- bool isAcceptableDecl(NamedDecl *D) const {
- return D->isInIdentifierNamespace(IDNS);
- }
-
- /// \brief Returns the identifier namespace mask for this lookup.
- unsigned getIdentifierNamespace() const {
- return IDNS;
- }
-
- /// \brief Returns whether these results arose from performing a
- /// lookup into a class.
- bool isClassLookup() const {
- return NamingClass != 0;
- }
-
- /// \brief Returns the 'naming class' for this lookup, i.e. the
- /// class which was looked into to find these results.
- ///
- /// C++0x [class.access.base]p5:
- /// The access to a member is affected by the class in which the
- /// member is named. This naming class is the class in which the
- /// member name was looked up and found. [Note: this class can be
- /// explicit, e.g., when a qualified-id is used, or implicit,
- /// e.g., when a class member access operator (5.2.5) is used
- /// (including cases where an implicit "this->" is added). If both
- /// a class member access operator and a qualified-id are used to
- /// name the member (as in p->T::m), the class naming the member
- /// is the class named by the nested-name-specifier of the
- /// qualified-id (that is, T). -- end note ]
- ///
- /// This is set by the lookup routines when they find results in a class.
- CXXRecordDecl *getNamingClass() const {
- return NamingClass;
- }
-
- /// \brief Sets the 'naming class' for this lookup.
- void setNamingClass(CXXRecordDecl *Record) {
- NamingClass = Record;
- }
-
- /// \brief Returns the base object type associated with this lookup;
- /// important for [class.protected]. Most lookups do not have an
- /// associated base object.
- QualType getBaseObjectType() const {
- return BaseObjectType;
- }
-
- /// \brief Sets the base object type for this lookup.
- void setBaseObjectType(QualType T) {
- BaseObjectType = T;
- }
-
- /// \brief Add a declaration to these results with its natural access.
- /// Does not test the acceptance criteria.
- void addDecl(NamedDecl *D) {
- addDecl(D, D->getAccess());
- }
-
- /// \brief Add a declaration to these results with the given access.
- /// Does not test the acceptance criteria.
- void addDecl(NamedDecl *D, AccessSpecifier AS) {
- Decls.addDecl(D, AS);
- ResultKind = Found;
- }
-
- /// \brief Add all the declarations from another set of lookup
- /// results.
- void addAllDecls(const LookupResult &Other) {
- Decls.append(Other.Decls.begin(), Other.Decls.end());
- ResultKind = Found;
- }
-
- /// \brief Determine whether no result was found because we could not
- /// search into dependent base classes of the current instantiation.
- bool wasNotFoundInCurrentInstantiation() const {
- return ResultKind == NotFoundInCurrentInstantiation;
- }
-
- /// \brief Note that while no result was found in the current instantiation,
- /// there were dependent base classes that could not be searched.
- void setNotFoundInCurrentInstantiation() {
- assert(ResultKind == NotFound && Decls.empty());
- ResultKind = NotFoundInCurrentInstantiation;
- }
-
- /// \brief Resolves the result kind of the lookup, possibly hiding
- /// decls.
- ///
- /// This should be called in any environment where lookup might
- /// generate multiple lookup results.
- void resolveKind();
-
- /// \brief Re-resolves the result kind of the lookup after a set of
- /// removals has been performed.
- void resolveKindAfterFilter() {
- if (Decls.empty()) {
- if (ResultKind != NotFoundInCurrentInstantiation)
- ResultKind = NotFound;
- } else {
- ResultKind = Found;
- resolveKind();
-
- if (Paths && (ResultKind != Ambiguous)) {
- deletePaths(Paths);
- Paths = 0;
- }
- }
- }
-
- template <class DeclClass>
- DeclClass *getAsSingle() const {
- if (getResultKind() != Found) return 0;
- return dyn_cast<DeclClass>(getFoundDecl());
- }
-
- /// \brief Fetch the unique decl found by this lookup. Asserts
- /// that one was found.
- ///
- /// This is intended for users who have examined the result kind
- /// and are certain that there is only one result.
- NamedDecl *getFoundDecl() const {
- assert(getResultKind() == Found
- && "getFoundDecl called on non-unique result");
- return (*begin())->getUnderlyingDecl();
- }
-
- /// Fetches a representative decl. Useful for lazy diagnostics.
- NamedDecl *getRepresentativeDecl() const {
- assert(!Decls.empty() && "cannot get representative of empty set");
- return *begin();
- }
-
- /// \brief Asks if the result is a single tag decl.
- bool isSingleTagDecl() const {
- return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
- }
-
- /// \brief Make these results show that the name was found in
- /// base classes of different types.
- ///
- /// The given paths object is copied and invalidated.
- void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
-
- /// \brief Make these results show that the name was found in
- /// distinct base classes of the same type.
- ///
- /// The given paths object is copied and invalidated.
- void setAmbiguousBaseSubobjects(CXXBasePaths &P);
-
- /// \brief Make these results show that the name was found in
- /// different contexts and a tag decl was hidden by an ordinary
- /// decl in a different context.
- void setAmbiguousQualifiedTagHiding() {
- setAmbiguous(AmbiguousTagHiding);
- }
-
- /// \brief Clears out any current state.
- void clear() {
- ResultKind = NotFound;
- Decls.clear();
- if (Paths) deletePaths(Paths);
- Paths = NULL;
- }
-
- /// \brief Clears out any current state and re-initializes for a
- /// different kind of lookup.
- void clear(Sema::LookupNameKind Kind) {
- clear();
- LookupKind = Kind;
- configure();
- }
-
- /// \brief Change this lookup's redeclaration kind.
- void setRedeclarationKind(Sema::RedeclarationKind RK) {
- Redecl = RK;
- configure();
- }
-
- void print(llvm::raw_ostream &);
-
- /// Suppress the diagnostics that would normally fire because of this
- /// lookup. This happens during (e.g.) redeclaration lookups.
- void suppressDiagnostics() {
- Diagnose = false;
- }
-
- /// Determines whether this lookup is suppressing diagnostics.
- bool isSuppressingDiagnostics() const {
- return Diagnose;
- }
-
- /// Sets a 'context' source range.
- void setContextRange(SourceRange SR) {
- NameContextRange = SR;
- }
-
- /// Gets the source range of the context of this name; for C++
- /// qualified lookups, this is the source range of the scope
- /// specifier.
- SourceRange getContextRange() const {
- return NameContextRange;
- }
-
- /// Gets the location of the identifier. This isn't always defined:
- /// sometimes we're doing lookups on synthesized names.
- SourceLocation getNameLoc() const {
- return NameLoc;
- }
-
- /// \brief Get the Sema object that this lookup result is searching
- /// with.
- Sema &getSema() const { return SemaRef; }
-
- /// A class for iterating through a result set and possibly
- /// filtering out results. The results returned are possibly
- /// sugared.
- class Filter {
- LookupResult &Results;
- LookupResult::iterator I;
- bool Changed;
-#ifndef NDEBUG
- bool CalledDone;
-#endif
-
- friend class LookupResult;
- Filter(LookupResult &Results)
- : Results(Results), I(Results.begin()), Changed(false)
-#ifndef NDEBUG
- , CalledDone(false)
-#endif
- {}
-
- public:
-#ifndef NDEBUG
- ~Filter() {
- assert(CalledDone &&
- "LookupResult::Filter destroyed without done() call");
- }
-#endif
-
- bool hasNext() const {
- return I != Results.end();
- }
-
- NamedDecl *next() {
- assert(I != Results.end() && "next() called on empty filter");
- return *I++;
- }
-
- /// Erase the last element returned from this iterator.
- void erase() {
- Results.Decls.erase(--I);
- Changed = true;
- }
-
- /// Replaces the current entry with the given one, preserving the
- /// access bits.
- void replace(NamedDecl *D) {
- Results.Decls.replace(I-1, D);
- Changed = true;
- }
-
- /// Replaces the current entry with the given one.
- void replace(NamedDecl *D, AccessSpecifier AS) {
- Results.Decls.replace(I-1, D, AS);
- Changed = true;
- }
-
- void done() {
-#ifndef NDEBUG
- assert(!CalledDone && "done() called twice");
- CalledDone = true;
-#endif
-
- if (Changed)
- Results.resolveKindAfterFilter();
- }
- };
-
- /// Create a filter for this result set.
- Filter makeFilter() {
- return Filter(*this);
- }
-
-private:
- void diagnose() {
- if (isAmbiguous())
- SemaRef.DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && SemaRef.getLangOptions().AccessControl)
- SemaRef.CheckLookupAccess(*this);
- }
-
- void setAmbiguous(AmbiguityKind AK) {
- ResultKind = Ambiguous;
- Ambiguity = AK;
- }
-
- void addDeclsFromBasePaths(const CXXBasePaths &P);
- void configure();
-
- // Sanity checks.
- void sanity() const {
- assert(ResultKind != NotFound || Decls.size() == 0);
- assert(ResultKind != Found || Decls.size() == 1);
- assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
- (Decls.size() == 1 &&
- isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
- assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
- assert(ResultKind != Ambiguous || Decls.size() > 1 ||
- (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
- assert((Paths != NULL) == (ResultKind == Ambiguous &&
- (Ambiguity == AmbiguousBaseSubobjectTypes ||
- Ambiguity == AmbiguousBaseSubobjects)));
- }
-
- bool sanityCheckUnresolved() const {
- for (iterator I = begin(), E = end(); I != E; ++I)
- if (isa<UnresolvedUsingValueDecl>(*I))
- return true;
- return false;
- }
-
- static void deletePaths(CXXBasePaths *);
-
- // Results.
- LookupResultKind ResultKind;
- AmbiguityKind Ambiguity; // ill-defined unless ambiguous
- UnresolvedSet<8> Decls;
- CXXBasePaths *Paths;
- CXXRecordDecl *NamingClass;
- QualType BaseObjectType;
-
- // Parameters.
- Sema &SemaRef;
- DeclarationName Name;
- SourceLocation NameLoc;
- SourceRange NameContextRange;
- Sema::LookupNameKind LookupKind;
- unsigned IDNS; // set by configure()
-
- bool Redecl;
-
- /// \brief True if tag declarations should be hidden if non-tags
- /// are present
- bool HideTags;
-
- bool Diagnose;
-};
-
- /// \brief Consumes visible declarations found when searching for
- /// all visible names within a given scope or context.
- ///
- /// This abstract class is meant to be subclassed by clients of \c
- /// Sema::LookupVisibleDecls(), each of which should override the \c
- /// FoundDecl() function to process declarations as they are found.
- class VisibleDeclConsumer {
- public:
- /// \brief Destroys the visible declaration consumer.
- virtual ~VisibleDeclConsumer();
-
- /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
- /// declaration visible from the current scope or context.
- ///
- /// \param ND the declaration found.
- ///
- /// \param Hiding a declaration that hides the declaration \p ND,
- /// or NULL if no such declaration exists.
- ///
- /// \param InBaseClass whether this declaration was found in base
- /// class of the context we searched.
- virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
- bool InBaseClass) = 0;
- };
-
-/// \brief A class for storing results from argument-dependent lookup.
-class ADLResult {
-private:
- /// A map from canonical decls to the 'most recent' decl.
- llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
-
-public:
- /// Adds a new ADL candidate to this map.
- void insert(NamedDecl *D);
-
- /// Removes any data associated with a given decl.
- void erase(NamedDecl *D) {
- Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
- }
-
- class iterator {
- typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
- inner_iterator iter;
-
- friend class ADLResult;
- iterator(const inner_iterator &iter) : iter(iter) {}
- public:
- iterator() {}
-
- iterator &operator++() { ++iter; return *this; }
- iterator operator++(int) { return iterator(iter++); }
-
- NamedDecl *operator*() const { return iter->second; }
-
- bool operator==(const iterator &other) const { return iter == other.iter; }
- bool operator!=(const iterator &other) const { return iter != other.iter; }
- };
-
- iterator begin() { return iterator(Decls.begin()); }
- iterator end() { return iterator(Decls.end()); }
-};
-
-}
-
-#endif
diff --git a/lib/Sema/Makefile b/lib/Sema/Makefile
index 90f2dffa0f1b..2c02739d268f 100644
--- a/lib/Sema/Makefile
+++ b/lib/Sema/Makefile
@@ -14,7 +14,6 @@
CLANG_LEVEL := ../..
LIBRARYNAME := clangSema
-BUILD_ARCHIVE = 1
include $(CLANG_LEVEL)/Makefile
diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
deleted file mode 100644
index bb0bd9e1cb5e..000000000000
--- a/lib/Sema/ParseAST.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the clang::ParseAST method.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Sema/ParseAST.h"
-#include "Sema.h"
-#include "clang/Sema/CodeCompleteConsumer.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Parse/Parser.h"
-#include <cstdio>
-
-using namespace clang;
-
-static void DumpRecordLayouts(ASTContext &C) {
- for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end();
- I != E; ++I) {
- const RecordType *RT = dyn_cast<RecordType>(*I);
- if (!RT)
- continue;
-
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD || RD->isImplicit() || RD->isDependentType() ||
- RD->isInvalidDecl() || !RD->getDefinition())
- continue;
-
- // FIXME: Do we really need to hard code this?
- if (RD->getQualifiedNameAsString() == "__va_list_tag")
- continue;
-
- C.DumpRecordLayout(RD, llvm::errs());
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Public interface to the file
-//===----------------------------------------------------------------------===//
-
-/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
-/// the file is parsed. This inserts the parsed decls into the translation unit
-/// held by Ctx.
-///
-void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
- ASTContext &Ctx, bool PrintStats,
- bool CompleteTranslationUnit,
- CodeCompleteConsumer *CompletionConsumer) {
- // Collect global stats on Decls/Stmts (until we have a module streamer).
- if (PrintStats) {
- Decl::CollectingStats(true);
- Stmt::CollectingStats(true);
- }
-
- Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
- Parser P(PP, S);
- PP.EnterMainSourceFile();
-
- // Initialize the parser.
- P.Initialize();
-
- Consumer->Initialize(Ctx);
-
- if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
- SC->InitializeSema(S);
-
- if (ExternalASTSource *External = Ctx.getExternalSource()) {
- if (ExternalSemaSource *ExternalSema =
- dyn_cast<ExternalSemaSource>(External))
- ExternalSema->InitializeSema(S);
-
- External->StartTranslationUnit(Consumer);
- }
-
- Parser::DeclGroupPtrTy ADecl;
-
- while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
- // If we got a null return and something *was* parsed, ignore it. This
- // is due to a top-level semicolon, an action override, or a parse error
- // skipping something.
- if (ADecl)
- Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
- };
- // Check for any pending objective-c implementation decl.
- while ((ADecl = P.RetrievePendingObjCImpDecl()))
- Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
-
- // Process any TopLevelDecls generated by #pragma weak.
- for (llvm::SmallVector<Decl*,2>::iterator
- I = S.WeakTopLevelDecls().begin(),
- E = S.WeakTopLevelDecls().end(); I != E; ++I)
- Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
-
- // Dump record layouts, if requested.
- if (PP.getLangOptions().DumpRecordLayouts)
- DumpRecordLayouts(Ctx);
-
- Consumer->HandleTranslationUnit(Ctx);
-
- if (ExternalSemaSource *ESS =
- dyn_cast_or_null<ExternalSemaSource>(Ctx.getExternalSource()))
- ESS->ForgetSema();
-
- if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
- SC->ForgetSema();
-
- if (PrintStats) {
- fprintf(stderr, "\nSTATISTICS:\n");
- P.getActions().PrintStats();
- Ctx.PrintStats();
- Decl::PrintStats();
- Stmt::PrintStats();
- Consumer->PrintStats();
- }
-}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index cddc84eeedff..17817d41691b 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -12,26 +12,36 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
#include "TargetAttributesSema.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/APFloat.h"
+#include "clang/Sema/CXXFieldCollector.h"
#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/ASTConsumer.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
using namespace clang;
+using namespace sema;
FunctionScopeInfo::~FunctionScopeInfo() { }
void FunctionScopeInfo::Clear(unsigned NumErrors) {
- NeedsScopeChecking = false;
+ HasBranchProtectedScope = false;
+ HasBranchIntoScope = false;
+ HasIndirectGoto = false;
+
LabelMap.clear();
SwitchStack.clear();
Returns.clear();
@@ -40,13 +50,13 @@ void FunctionScopeInfo::Clear(unsigned NumErrors) {
BlockScopeInfo::~BlockScopeInfo() { }
-void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+void Sema::ActOnTranslationUnitScope(Scope *S) {
TUScope = S;
PushDeclContext(S, Context.getTranslationUnitDecl());
VAListTagName = PP.getIdentifierInfo("__va_list_tag");
- if (!Context.isInt128Installed() && // May be set by PCHReader.
+ if (!Context.isInt128Installed() && // May be set by ASTReader.
PP.getTargetInfo().getPointerWidth(0) >= 64) {
TypeSourceInfo *TInfo;
@@ -68,7 +78,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
if (!PP.getLangOptions().ObjC1) return;
- // Built-in ObjC types may already be set by PCHReader (hence isNull checks).
+ // Built-in ObjC types may already be set by ASTReader (hence isNull checks).
if (Context.getObjCSelType().isNull()) {
// Create the built-in typedef for 'SEL'.
QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
@@ -113,7 +123,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
PushOnScopeChains(ClassTypedef, TUScope);
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
Context.ObjCClassRedefinitionType = Context.getObjCClassType();
- }
+ }
}
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
@@ -123,9 +133,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0),
- PackContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
- IdResolver(pp.getLangOptions()), StdNamespace(0), StdBadAlloc(0),
- GlobalNewDeleteDeclared(false),
+ PackContext(0), VisContext(0), ParsingDeclDepth(0),
+ IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false),
CompleteTranslationUnit(CompleteTranslationUnit),
NumSFINAEErrors(0), SuppressAccessChecking(false),
NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0),
@@ -140,22 +149,52 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
&Context);
ExprEvalContexts.push_back(
- ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+ ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+
+ FunctionScopes.push_back(new FunctionScopeInfo(Diags.getNumErrors()));
+}
+
+void Sema::Initialize() {
+ // Tell the AST consumer about this Sema object.
+ Consumer.Initialize(Context);
+
+ // FIXME: Isn't this redundant with the initialization above?
+ if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+ SC->InitializeSema(*this);
+
+ // Tell the external Sema source about this Sema object.
+ if (ExternalSemaSource *ExternalSema
+ = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+ ExternalSema->InitializeSema(*this);
}
Sema::~Sema() {
if (PackContext) FreePackedContext();
+ if (VisContext) FreeVisContext();
delete TheTargetAttributesSema;
- while (!FunctionScopes.empty())
- PopFunctionOrBlockScope();
+
+ // Kill all the active scopes.
+ for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
+ delete FunctionScopes[I];
+ if (FunctionScopes.size() == 1)
+ delete FunctionScopes[0];
+
+ // Tell the SemaConsumer to forget about us; we're going out of scope.
+ if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+ SC->ForgetSema();
+
+ // Detach from the external Sema source.
+ if (ExternalSemaSource *ExternalSema
+ = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+ ExternalSema->ForgetSema();
}
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
-/// If isLvalue, the result of the cast is an lvalue.
+/// The result is of the given category.
void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
- CastExpr::CastKind Kind,
- bool isLvalue, CXXBaseSpecifierArray BasePath) {
+ CastKind Kind, ExprValueKind VK,
+ const CXXCastPath *BasePath) {
QualType ExprTy = Context.getCanonicalType(Expr->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
@@ -173,8 +212,8 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
// If this is a derived-to-base cast to a through a virtual base, we
// need a vtable.
- if (Kind == CastExpr::CK_DerivedToBase &&
- BasePathInvolvesVirtualBase(BasePath)) {
+ if (Kind == CK_DerivedToBase &&
+ BasePathInvolvesVirtualBase(*BasePath)) {
QualType T = Expr->getType();
if (const PointerType *Pointer = T->getAs<PointerType>())
T = Pointer->getPointeeType();
@@ -184,53 +223,96 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
}
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
- if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
+ if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
- ImpCast->setLvalueCast(isLvalue);
+ ImpCast->setValueKind(VK);
return;
}
}
- Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, isLvalue);
+ Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK);
}
-void Sema::DeleteExpr(ExprTy *E) {
- if (E) static_cast<Expr*>(E)->Destroy(Context);
+ExprValueKind Sema::CastCategory(Expr *E) {
+ Expr::Classification Classification = E->Classify(Context);
+ return Classification.isRValue() ? VK_RValue :
+ (Classification.isLValue() ? VK_LValue : VK_XValue);
}
-void Sema::DeleteStmt(StmtTy *S) {
- if (S) static_cast<Stmt*>(S)->Destroy(Context);
+
+/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
+static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
+ if (D->isUsed())
+ return true;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // UnusedFileScopedDecls stores the first declaration.
+ // The declaration may have become definition so check again.
+ const FunctionDecl *DeclToCheck;
+ if (FD->hasBody(DeclToCheck))
+ return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+ // Later redecls may add new information resulting in not having to warn,
+ // so check again.
+ DeclToCheck = FD->getMostRecentDeclaration();
+ if (DeclToCheck != FD)
+ return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+ }
+
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ // UnusedFileScopedDecls stores the first declaration.
+ // The declaration may have become definition so check again.
+ const VarDecl *DeclToCheck = VD->getDefinition();
+ if (DeclToCheck)
+ return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+ // Later redecls may add new information resulting in not having to warn,
+ // so check again.
+ DeclToCheck = VD->getMostRecentDeclaration();
+ if (DeclToCheck != VD)
+ return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+ }
+
+ return false;
}
/// ActOnEndOfTranslationUnit - This is called at the very end of the
/// translation unit when EOF is reached and all but the top-level scope is
/// popped.
-void Sema::ActOnEndOfTranslationUnit() {
- while (1) {
- // C++: Perform implicit template instantiations.
- //
- // FIXME: When we perform these implicit instantiations, we do not carefully
- // keep track of the point of instantiation (C++ [temp.point]). This means
- // that name lookup that occurs within the template instantiation will
- // always happen at the end of the translation unit, so it will find
- // some names that should not be found. Although this is common behavior
- // for C++ compilers, it is technically wrong. In the future, we either need
- // to be able to filter the results of name lookup or we need to perform
- // template instantiations earlier.
- PerformPendingImplicitInstantiations();
-
- /// If DefinedUsedVTables ends up marking any virtual member
- /// functions it might lead to more pending template
- /// instantiations, which is why we need to loop here.
- if (!DefineUsedVTables())
- break;
- }
+void Sema::ActOnEndOfTranslationUnit() {
+ // At PCH writing, implicit instantiations and VTable handling info are
+ // stored and performed when the PCH is included.
+ if (CompleteTranslationUnit)
+ while (1) {
+ // C++: Perform implicit template instantiations.
+ //
+ // FIXME: When we perform these implicit instantiations, we do not
+ // carefully keep track of the point of instantiation (C++ [temp.point]).
+ // This means that name lookup that occurs within the template
+ // instantiation will always happen at the end of the translation unit,
+ // so it will find some names that should not be found. Although this is
+ // common behavior for C++ compilers, it is technically wrong. In the
+ // future, we either need to be able to filter the results of name lookup
+ // or we need to perform template instantiations earlier.
+ PerformPendingInstantiations();
+
+ /// If DefinedUsedVTables ends up marking any virtual member
+ /// functions it might lead to more pending template
+ /// instantiations, which is why we need to loop here.
+ if (!DefineUsedVTables())
+ break;
+ }
- // Remove functions that turned out to be used.
- UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(),
- UnusedStaticFuncs.end(),
- std::bind2nd(std::mem_fun(&FunctionDecl::isUsed),
- true)),
- UnusedStaticFuncs.end());
+ // Remove file scoped decls that turned out to be used.
+ UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
+ UnusedFileScopedDecls.end(),
+ std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
+ this)),
+ UnusedFileScopedDecls.end());
+
+ if (!CompleteTranslationUnit) {
+ TUScope = 0;
+ return;
+ }
// Check for #pragma weak identifiers that were never declared
// FIXME: This will cause diagnostics to be emitted in a non-determinstic
@@ -244,9 +326,6 @@ void Sema::ActOnEndOfTranslationUnit() {
<< I->first;
}
- if (!CompleteTranslationUnit)
- return;
-
// C99 6.9.2p2:
// A declaration of an identifier for an object that has file
// scope without an initializer, and without a storage-class
@@ -293,14 +372,28 @@ void Sema::ActOnEndOfTranslationUnit() {
}
- // Output warning for unused functions.
- for (std::vector<FunctionDecl*>::iterator
- F = UnusedStaticFuncs.begin(),
- FEnd = UnusedStaticFuncs.end();
- F != FEnd;
- ++F)
- Diag((*F)->getLocation(), diag::warn_unused_function) << (*F)->getDeclName();
-
+ // Output warning for unused file scoped decls.
+ for (llvm::SmallVectorImpl<const DeclaratorDecl*>::iterator
+ I = UnusedFileScopedDecls.begin(),
+ E = UnusedFileScopedDecls.end(); I != E; ++I) {
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+ const FunctionDecl *DiagD;
+ if (!FD->hasBody(DiagD))
+ DiagD = FD;
+ Diag(DiagD->getLocation(),
+ isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
+ : diag::warn_unused_function)
+ << DiagD->getDeclName();
+ } else {
+ const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
+ if (!DiagD)
+ DiagD = cast<VarDecl>(*I);
+ Diag(DiagD->getLocation(), diag::warn_unused_variable)
+ << DiagD->getDeclName();
+ }
+ }
+
+ TUScope = 0;
}
@@ -418,11 +511,11 @@ Scope *Sema::getScopeForContext(DeclContext *Ctx) {
/// \brief Enter a new function scope
void Sema::PushFunctionScope() {
- if (FunctionScopes.empty()) {
- // Use the "top" function scope rather than having to allocate memory for
- // a new scope.
- TopFunctionScope.Clear(getDiagnostics().getNumErrors());
- FunctionScopes.push_back(&TopFunctionScope);
+ if (FunctionScopes.size() == 1) {
+ // Use the "top" function scope rather than having to allocate
+ // memory for a new scope.
+ FunctionScopes.back()->Clear(getDiagnostics().getNumErrors());
+ FunctionScopes.push_back(FunctionScopes.back());
return;
}
@@ -436,21 +529,17 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
}
void Sema::PopFunctionOrBlockScope() {
- if (FunctionScopes.back() != &TopFunctionScope)
- delete FunctionScopes.back();
- else
- TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-
- FunctionScopes.pop_back();
+ FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
+ assert(!FunctionScopes.empty() && "mismatched push/pop!");
+ if (FunctionScopes.back() != Scope)
+ delete Scope;
}
/// \brief Determine whether any errors occurred within this function/method/
/// block.
bool Sema::hasAnyErrorsInThisFunction() const {
- unsigned NumErrors = TopFunctionScope.NumErrorsAtStartOfFunction;
- if (!FunctionScopes.empty())
- NumErrors = FunctionScopes.back()->NumErrorsAtStartOfFunction;
- return NumErrors != getDiagnostics().getNumErrors();
+ return getCurFunction()->NumErrorsAtStartOfFunction
+ != getDiagnostics().getNumErrors();
}
BlockScopeInfo *Sema::getCurBlock() {
@@ -462,3 +551,21 @@ BlockScopeInfo *Sema::getCurBlock() {
// Pin this vtable to this file.
ExternalSemaSource::~ExternalSemaSource() {}
+
+void PrettyDeclStackTraceEntry::print(llvm::raw_ostream &OS) const {
+ SourceLocation Loc = this->Loc;
+ if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
+ if (Loc.isValid()) {
+ Loc.print(OS, S.getSourceManager());
+ OS << ": ";
+ }
+ OS << Message;
+
+ if (TheDecl && isa<NamedDecl>(TheDecl)) {
+ std::string Name = cast<NamedDecl>(TheDecl)->getNameAsString();
+ if (!Name.empty())
+ OS << " '" << Name << '\'';
+ }
+
+ OS << '\n';
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
deleted file mode 100644
index 8336918c134e..000000000000
--- a/lib/Sema/Sema.h
+++ /dev/null
@@ -1,4655 +0,0 @@
-//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Sema class, which performs semantic analysis and
-// builds ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_H
-#define LLVM_CLANG_AST_SEMA_H
-
-#include "IdentifierResolver.h"
-#include "CXXFieldCollector.h"
-#include "SemaOverload.h"
-#include "SemaTemplate.h"
-#include "AnalysisBasedWarnings.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/FullExpr.h"
-#include "clang/Parse/Action.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include <deque>
-#include <list>
-#include <map>
-#include <string>
-#include <vector>
-
-namespace llvm {
- class APSInt;
-}
-
-namespace clang {
- class ASTContext;
- class ASTConsumer;
- class CodeCompleteConsumer;
- class Preprocessor;
- class Decl;
- class DeclContext;
- class DeclSpec;
- class ExternalSemaSource;
- class NamedDecl;
- class Stmt;
- class Expr;
- class InitListExpr;
- class ParenListExpr;
- class DesignatedInitExpr;
- class CallExpr;
- class DeclRefExpr;
- class UnresolvedLookupExpr;
- class UnresolvedMemberExpr;
- class VarDecl;
- class ParmVarDecl;
- class TypedefDecl;
- class FunctionDecl;
- class QualType;
- class LangOptions;
- class Token;
- class IntegerLiteral;
- class StringLiteral;
- class ArrayType;
- class LabelStmt;
- class SwitchStmt;
- class CXXTryStmt;
- class ExtVectorType;
- class TypedefDecl;
- class TemplateDecl;
- class TemplateArgument;
- class TemplateArgumentLoc;
- class TemplateArgumentList;
- class TemplateParameterList;
- class TemplateTemplateParmDecl;
- class ClassTemplatePartialSpecializationDecl;
- class ClassTemplateDecl;
- class ObjCInterfaceDecl;
- class ObjCCompatibleAliasDecl;
- class ObjCProtocolDecl;
- class ObjCImplDecl;
- class ObjCImplementationDecl;
- class ObjCCategoryImplDecl;
- class ObjCCategoryDecl;
- class ObjCIvarDecl;
- class ObjCMethodDecl;
- class ObjCPropertyDecl;
- class ObjCContainerDecl;
- class PseudoDestructorTypeStorage;
- class FunctionProtoType;
- class CXXBasePath;
- class CXXBasePaths;
- class CXXTemporary;
- class LookupResult;
- class InitializedEntity;
- class InitializationKind;
- class InitializationSequence;
- class VisibleDeclConsumer;
- class TargetAttributesSema;
- class ADLResult;
-
-/// \brief Retains information about a function, method, or block that is
-/// currently being parsed.
-struct FunctionScopeInfo {
- /// \brief Whether this scope information structure defined information for
- /// a block.
- bool IsBlockInfo;
-
- /// \brief Set true when a function, method contains a VLA or ObjC try block,
- /// which introduce scopes that need to be checked for goto conditions. If a
- /// function does not contain this, then it need not have the jump checker run
- /// on it.
- bool NeedsScopeChecking;
-
- /// \brief The number of errors that had occurred before starting this
- /// function or block.
- unsigned NumErrorsAtStartOfFunction;
-
- /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
- /// it (which acts like the label decl in some ways). Forward referenced
- /// labels have a LabelStmt created for them with a null location & SubStmt.
- llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
-
- /// SwitchStack - This is the current set of active switch statements in the
- /// block.
- llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
-
- /// \brief The list of return statements that occur within the function or
- /// block, if there is any chance of applying the named return value
- /// optimization.
- llvm::SmallVector<ReturnStmt *, 4> Returns;
-
- FunctionScopeInfo(unsigned NumErrors)
- : IsBlockInfo(false), NeedsScopeChecking(false),
- NumErrorsAtStartOfFunction(NumErrors) { }
-
- virtual ~FunctionScopeInfo();
-
- /// \brief Clear out the information in this function scope, making it
- /// suitable for reuse.
- void Clear(unsigned NumErrors);
-
- static bool classof(const FunctionScopeInfo *FSI) { return true; }
-};
-
-
-/// \brief Retains information about a block that is currently being parsed.
-struct BlockScopeInfo : FunctionScopeInfo {
- bool hasBlockDeclRefExprs;
-
- BlockDecl *TheDecl;
-
- /// TheScope - This is the scope for the block itself, which contains
- /// arguments etc.
- Scope *TheScope;
-
- /// ReturnType - The return type of the block, or null if the block
- /// signature didn't provide an explicit return type.
- QualType ReturnType;
-
- /// BlockType - The function type of the block, if one was given.
- /// Its return type may be BuiltinType::Dependent.
- QualType FunctionType;
-
- BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
- : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false),
- TheDecl(Block), TheScope(BlockScope)
- {
- IsBlockInfo = true;
- }
-
- virtual ~BlockScopeInfo();
-
- static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
- static bool classof(const BlockScopeInfo *BSI) { return true; }
-};
-
-/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
-/// parsing.
-///
-/// LocInfoType is a "transient" type, only needed for passing to/from Parser
-/// and Sema, when we want to preserve type source info for a parsed type.
-/// It will not participate in the type system semantics in any way.
-class LocInfoType : public Type {
- enum {
- // The last number that can fit in Type's TC.
- // Avoids conflict with an existing Type class.
- LocInfo = Type::TypeLast + 1
- };
-
- TypeSourceInfo *DeclInfo;
-
- LocInfoType(QualType ty, TypeSourceInfo *TInfo)
- : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(TInfo) {
- assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
- }
- friend class Sema;
-
-public:
- QualType getType() const { return getCanonicalTypeInternal(); }
- TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
-
- virtual void getAsStringInternal(std::string &Str,
- const PrintingPolicy &Policy) const;
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == (TypeClass)LocInfo;
- }
- static bool classof(const LocInfoType *) { return true; }
-};
-
-/// Sema - This implements semantic analysis and AST building for C.
-class Sema : public Action {
- Sema(const Sema&); // DO NOT IMPLEMENT
- void operator=(const Sema&); // DO NOT IMPLEMENT
- mutable const TargetAttributesSema* TheTargetAttributesSema;
-public:
- const LangOptions &LangOpts;
- Preprocessor &PP;
- ASTContext &Context;
- ASTConsumer &Consumer;
- Diagnostic &Diags;
- SourceManager &SourceMgr;
-
- /// \brief Source of additional semantic information.
- ExternalSemaSource *ExternalSource;
-
- /// \brief Code-completion consumer.
- CodeCompleteConsumer *CodeCompleter;
-
- /// CurContext - This is the current declaration context of parsing.
- DeclContext *CurContext;
-
- /// VAListTagName - The declaration name corresponding to __va_list_tag.
- /// This is used as part of a hack to omit that class from ADL results.
- DeclarationName VAListTagName;
-
- /// A RAII object to temporarily push a declaration context.
- class ContextRAII {
- private:
- Sema &S;
- DeclContext *SavedContext;
-
- public:
- ContextRAII(Sema &S, DeclContext *ContextToPush)
- : S(S), SavedContext(S.CurContext) {
- assert(ContextToPush && "pushing null context");
- S.CurContext = ContextToPush;
- }
-
- void pop() {
- if (!SavedContext) return;
- S.CurContext = SavedContext;
- SavedContext = 0;
- }
-
- ~ContextRAII() {
- pop();
- }
- };
-
- /// PackContext - Manages the stack for #pragma pack. An alignment
- /// of 0 indicates default alignment.
- void *PackContext; // Really a "PragmaPackStack*"
-
- /// \brief Stack containing information about each of the nested function,
- /// block, and method scopes that are currently active.
- llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
-
- /// \brief Cached function scope object used for the top function scope
- /// and when there is no function scope (in error cases).
- ///
- /// This should never be accessed directly; rather, it's address will be
- /// pushed into \c FunctionScopes when we want to re-use it.
- FunctionScopeInfo TopFunctionScope;
-
- /// ExprTemporaries - This is the stack of temporaries that are created by
- /// the current full expression.
- llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries;
-
- /// ExtVectorDecls - This is a list all the extended vector types. This allows
- /// us to associate a raw vector type with one of the ext_vector type names.
- /// This is only necessary for issuing pretty diagnostics.
- llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
-
- /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
- llvm::OwningPtr<CXXFieldCollector> FieldCollector;
-
- typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
-
- /// PureVirtualClassDiagSet - a set of class declarations which we have
- /// emitted a list of pure virtual functions. Used to prevent emitting the
- /// same list more than once.
- llvm::OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
-
- /// \brief A mapping from external names to the most recent
- /// locally-scoped external declaration with that name.
- ///
- /// This map contains external declarations introduced in local
- /// scoped, e.g.,
- ///
- /// \code
- /// void f() {
- /// void foo(int, int);
- /// }
- /// \endcode
- ///
- /// Here, the name "foo" will be associated with the declaration on
- /// "foo" within f. This name is not visible outside of
- /// "f". However, we still find it in two cases:
- ///
- /// - If we are declaring another external with the name "foo", we
- /// can find "foo" as a previous declaration, so that the types
- /// of this external declaration can be checked for
- /// compatibility.
- ///
- /// - If we would implicitly declare "foo" (e.g., due to a call to
- /// "foo" in C when no prototype or definition is visible), then
- /// we find this declaration of "foo" and complain that it is
- /// not visible.
- llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls;
-
- /// \brief All the tentative definitions encountered in the TU.
- std::vector<VarDecl *> TentativeDefinitions;
-
- /// \brief The set of static functions seen so far that have not been used.
- std::vector<FunctionDecl*> UnusedStaticFuncs;
-
- class AccessedEntity {
- public:
- /// A member declaration found through lookup. The target is the
- /// member.
- enum MemberNonce { Member };
-
- /// A hierarchy (base-to-derived or derived-to-base) conversion.
- /// The target is the base class.
- enum BaseNonce { Base };
-
- bool isMemberAccess() const { return IsMember; }
-
- AccessedEntity(ASTContext &Context,
- MemberNonce _,
- CXXRecordDecl *NamingClass,
- DeclAccessPair FoundDecl,
- QualType BaseObjectType)
- : Access(FoundDecl.getAccess()), IsMember(true),
- Target(FoundDecl.getDecl()), NamingClass(NamingClass),
- BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) {
- }
-
- AccessedEntity(ASTContext &Context,
- BaseNonce _,
- CXXRecordDecl *BaseClass,
- CXXRecordDecl *DerivedClass,
- AccessSpecifier Access)
- : Access(Access), IsMember(false),
- Target(BaseClass), NamingClass(DerivedClass),
- Diag(0, Context.getDiagAllocator()) {
- }
-
- bool isQuiet() const { return Diag.getDiagID() == 0; }
-
- AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
- // These apply to member decls...
- NamedDecl *getTargetDecl() const { return Target; }
- CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
- // ...and these apply to hierarchy conversions.
- CXXRecordDecl *getBaseClass() const { return cast<CXXRecordDecl>(Target); }
- CXXRecordDecl *getDerivedClass() const { return NamingClass; }
-
- /// Retrieves the base object type, important when accessing
- /// an instance member.
- QualType getBaseObjectType() const { return BaseObjectType; }
-
- /// Sets a diagnostic to be performed. The diagnostic is given
- /// four (additional) arguments:
- /// %0 - 0 if the entity was private, 1 if protected
- /// %1 - the DeclarationName of the entity
- /// %2 - the TypeDecl type of the naming class
- /// %3 - the TypeDecl type of the declaring class
- void setDiag(const PartialDiagnostic &PDiag) {
- assert(isQuiet() && "partial diagnostic already defined");
- Diag = PDiag;
- }
- PartialDiagnostic &setDiag(unsigned DiagID) {
- assert(isQuiet() && "partial diagnostic already defined");
- assert(DiagID && "creating null diagnostic");
- Diag.Reset(DiagID);
- return Diag;
- }
- const PartialDiagnostic &getDiag() const {
- return Diag;
- }
-
- private:
- unsigned Access : 2;
- bool IsMember;
- NamedDecl *Target;
- CXXRecordDecl *NamingClass;
- QualType BaseObjectType;
- PartialDiagnostic Diag;
- };
-
- struct DelayedDiagnostic {
- enum DDKind { Deprecation, Access };
-
- unsigned char Kind; // actually a DDKind
- bool Triggered;
-
- SourceLocation Loc;
-
- union {
- /// Deprecation.
- struct { NamedDecl *Decl; } DeprecationData;
-
- /// Access control.
- char AccessData[sizeof(AccessedEntity)];
- };
-
- void destroy() {
- switch (Kind) {
- case Access: getAccessData().~AccessedEntity(); break;
- case Deprecation: break;
- }
- }
-
- static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
- NamedDecl *D) {
- DelayedDiagnostic DD;
- DD.Kind = Deprecation;
- DD.Triggered = false;
- DD.Loc = Loc;
- DD.DeprecationData.Decl = D;
- return DD;
- }
-
- static DelayedDiagnostic makeAccess(SourceLocation Loc,
- const AccessedEntity &Entity) {
- DelayedDiagnostic DD;
- DD.Kind = Access;
- DD.Triggered = false;
- DD.Loc = Loc;
- new (&DD.getAccessData()) AccessedEntity(Entity);
- return DD;
- }
-
- AccessedEntity &getAccessData() {
- return *reinterpret_cast<AccessedEntity*>(AccessData);
- }
- const AccessedEntity &getAccessData() const {
- return *reinterpret_cast<const AccessedEntity*>(AccessData);
- }
- };
-
- /// \brief The stack of diagnostics that were delayed due to being
- /// produced during the parsing of a declaration.
- llvm::SmallVector<DelayedDiagnostic, 8> DelayedDiagnostics;
-
- /// \brief The depth of the current ParsingDeclaration stack.
- /// If nonzero, we are currently parsing a declaration (and
- /// hence should delay deprecation warnings).
- unsigned ParsingDeclDepth;
-
- /// WeakUndeclaredIdentifiers - Identifiers contained in
- /// #pragma weak before declared. rare. may alias another
- /// identifier, declared or undeclared
- class WeakInfo {
- IdentifierInfo *alias; // alias (optional)
- SourceLocation loc; // for diagnostics
- bool used; // identifier later declared?
- public:
- WeakInfo()
- : alias(0), loc(SourceLocation()), used(false) {}
- WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
- : alias(Alias), loc(Loc), used(false) {}
- inline IdentifierInfo * getAlias() const { return alias; }
- inline SourceLocation getLocation() const { return loc; }
- void setUsed(bool Used=true) { used = Used; }
- inline bool getUsed() { return used; }
- bool operator==(WeakInfo RHS) const {
- return alias == RHS.getAlias() && loc == RHS.getLocation();
- }
- bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
- };
- llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
-
- /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
- /// #pragma weak during processing of other Decls.
- /// I couldn't figure out a clean way to generate these in-line, so
- /// we store them here and handle separately -- which is a hack.
- /// It would be best to refactor this.
- llvm::SmallVector<Decl*,2> WeakTopLevelDecl;
-
- IdentifierResolver IdResolver;
-
- /// Translation Unit Scope - useful to Objective-C actions that need
- /// to lookup file scope declarations in the "ordinary" C decl namespace.
- /// For example, user-defined classes, built-in "id" type, etc.
- Scope *TUScope;
-
- /// \brief The C++ "std" namespace, where the standard library resides.
- NamespaceDecl *StdNamespace;
-
- /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
- /// standard library.
- CXXRecordDecl *StdBadAlloc;
-
- /// A flag to remember whether the implicit forms of operator new and delete
- /// have been declared.
- bool GlobalNewDeleteDeclared;
-
- /// \brief The set of declarations that have been referenced within
- /// a potentially evaluated expression.
- typedef std::vector<std::pair<SourceLocation, Decl *> >
- PotentiallyReferencedDecls;
-
- /// \brief A set of diagnostics that may be emitted.
- typedef std::vector<std::pair<SourceLocation, PartialDiagnostic> >
- PotentiallyEmittedDiagnostics;
-
- /// \brief Data structure used to record current or nested
- /// expression evaluation contexts.
- struct ExpressionEvaluationContextRecord {
- /// \brief The expression evaluation context.
- ExpressionEvaluationContext Context;
-
- /// \brief The number of temporaries that were active when we
- /// entered this expression evaluation context.
- unsigned NumTemporaries;
-
- /// \brief The set of declarations referenced within a
- /// potentially potentially-evaluated context.
- ///
- /// When leaving a potentially potentially-evaluated context, each
- /// of these elements will be as referenced if the corresponding
- /// potentially potentially evaluated expression is potentially
- /// evaluated.
- PotentiallyReferencedDecls *PotentiallyReferenced;
-
- /// \brief The set of diagnostics to emit should this potentially
- /// potentially-evaluated context become evaluated.
- PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
-
- ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
- unsigned NumTemporaries)
- : Context(Context), NumTemporaries(NumTemporaries),
- PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
-
- void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
- if (!PotentiallyReferenced)
- PotentiallyReferenced = new PotentiallyReferencedDecls;
- PotentiallyReferenced->push_back(std::make_pair(Loc, Decl));
- }
-
- void addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD) {
- if (!PotentiallyDiagnosed)
- PotentiallyDiagnosed = new PotentiallyEmittedDiagnostics;
- PotentiallyDiagnosed->push_back(std::make_pair(Loc, PD));
- }
-
- void Destroy() {
- delete PotentiallyReferenced;
- delete PotentiallyDiagnosed;
- PotentiallyReferenced = 0;
- PotentiallyDiagnosed = 0;
- }
- };
-
- /// A stack of expression evaluation contexts.
- llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
-
- /// \brief Whether the code handled by Sema should be considered a
- /// complete translation unit or not.
- ///
- /// When true (which is generally the case), Sema will perform
- /// end-of-translation-unit semantic tasks (such as creating
- /// initializers for tentative definitions in C) once parsing has
- /// completed. This flag will be false when building PCH files,
- /// since a PCH file is by definition not a complete translation
- /// unit.
- bool CompleteTranslationUnit;
-
- llvm::BumpPtrAllocator BumpAlloc;
-
- /// \brief The number of SFINAE diagnostics that have been trapped.
- unsigned NumSFINAEErrors;
-
- typedef llvm::DenseMap<Selector, ObjCMethodList> MethodPool;
-
- /// Instance/Factory Method Pools - allows efficient lookup when typechecking
- /// messages to "id". We need to maintain a list, since selectors can have
- /// differing signatures across classes. In Cocoa, this happens to be
- /// extremely uncommon (only 1% of selectors are "overloaded").
- MethodPool InstanceMethodPool;
- MethodPool FactoryMethodPool;
-
- MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);
-
- /// Private Helper predicate to check for 'self'.
- bool isSelfExpr(Expr *RExpr);
-public:
- Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
- bool CompleteTranslationUnit = true,
- CodeCompleteConsumer *CompletionConsumer = 0);
- ~Sema();
-
- const LangOptions &getLangOptions() const { return LangOpts; }
- Diagnostic &getDiagnostics() const { return Diags; }
- SourceManager &getSourceManager() const { return SourceMgr; }
- const TargetAttributesSema &getTargetAttributesSema() const;
-
- /// \brief Helper class that creates diagnostics with optional
- /// template instantiation stacks.
- ///
- /// This class provides a wrapper around the basic DiagnosticBuilder
- /// class that emits diagnostics. SemaDiagnosticBuilder is
- /// responsible for emitting the diagnostic (as DiagnosticBuilder
- /// does) and, if the diagnostic comes from inside a template
- /// instantiation, printing the template instantiation stack as
- /// well.
- class SemaDiagnosticBuilder : public DiagnosticBuilder {
- Sema &SemaRef;
- unsigned DiagID;
-
- public:
- SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
- : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
-
- explicit SemaDiagnosticBuilder(Sema &SemaRef)
- : DiagnosticBuilder(DiagnosticBuilder::Suppress), SemaRef(SemaRef) { }
-
- ~SemaDiagnosticBuilder();
- };
-
- /// \brief Emit a diagnostic.
- SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
-
- /// \brief Emit a partial diagnostic.
- SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
-
- /// \brief Build a partial diagnostic.
- PartialDiagnostic PDiag(unsigned DiagID = 0) {
- return PartialDiagnostic(DiagID, Context.getDiagAllocator());
- }
-
- virtual void DeleteExpr(ExprTy *E);
- virtual void DeleteStmt(StmtTy *S);
-
- OwningExprResult Owned(Expr* E) {
- assert(!E || E->isRetained());
- return OwningExprResult(*this, E);
- }
- OwningExprResult Owned(ExprResult R) {
- if (R.isInvalid())
- return ExprError();
- assert(!R.get() || ((Expr*) R.get())->isRetained());
- return OwningExprResult(*this, R.get());
- }
- OwningStmtResult Owned(Stmt* S) {
- assert(!S || S->isRetained());
- return OwningStmtResult(*this, S);
- }
-
- virtual void ActOnEndOfTranslationUnit();
-
- Scope *getScopeForContext(DeclContext *Ctx);
-
- void PushFunctionScope();
- void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
- void PopFunctionOrBlockScope();
-
- /// getLabelMap() - Return the current label map. If we're in a block, we
- /// return it.
- llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
- if (FunctionScopes.empty())
- return TopFunctionScope.LabelMap;
-
- return FunctionScopes.back()->LabelMap;
- }
-
- /// getSwitchStack - This is returns the switch stack for the current block or
- /// function.
- llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
- if (FunctionScopes.empty())
- return TopFunctionScope.SwitchStack;
-
- return FunctionScopes.back()->SwitchStack;
- }
-
- /// \brief Determine whether the current function or block needs scope
- /// checking.
- bool &FunctionNeedsScopeChecking() {
- if (FunctionScopes.empty())
- return TopFunctionScope.NeedsScopeChecking;
-
- return FunctionScopes.back()->NeedsScopeChecking;
- }
-
- bool hasAnyErrorsInThisFunction() const;
-
- /// \brief Retrieve the current block, if any.
- BlockScopeInfo *getCurBlock();
-
- /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
- llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
-
- //===--------------------------------------------------------------------===//
- // Type Analysis / Processing: SemaType.cpp.
- //
-
- QualType adjustParameterType(QualType T);
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs);
- QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR) {
- return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR));
- }
- QualType BuildPointerType(QualType T,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildReferenceType(QualType T, bool LValueRef,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
- Expr *ArraySize, unsigned Quals,
- SourceRange Brackets, DeclarationName Entity);
- QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
- SourceLocation AttrLoc);
- QualType BuildFunctionType(QualType T,
- QualType *ParamTypes, unsigned NumParamTypes,
- bool Variadic, unsigned Quals,
- SourceLocation Loc, DeclarationName Entity);
- QualType BuildMemberPointerType(QualType T, QualType Class,
- SourceLocation Loc,
- DeclarationName Entity);
- QualType BuildBlockPointerType(QualType T,
- SourceLocation Loc, DeclarationName Entity);
- TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S,
- TagDecl **OwnedDecl = 0);
- TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
- TypeSourceInfo *ReturnTypeInfo);
- /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
- QualType CreateLocInfoType(QualType T, TypeSourceInfo *TInfo);
- DeclarationName GetNameForDeclarator(Declarator &D);
- DeclarationName GetNameFromUnqualifiedId(const UnqualifiedId &Name);
- static QualType GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo = 0);
- bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
- bool CheckDistantExceptionSpec(QualType T);
- bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
- bool CheckEquivalentExceptionSpec(
- const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc);
- bool CheckEquivalentExceptionSpec(
- const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
- const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc,
- bool *MissingExceptionSpecification = 0,
- bool *MissingEmptyExceptionSpecification = 0);
- bool CheckExceptionSpecSubset(
- const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
- const FunctionProtoType *Superset, SourceLocation SuperLoc,
- const FunctionProtoType *Subset, SourceLocation SubLoc);
- bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
- const FunctionProtoType *Target, SourceLocation TargetLoc,
- const FunctionProtoType *Source, SourceLocation SourceLoc);
-
- virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
-
- bool RequireCompleteType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD,
- std::pair<SourceLocation, PartialDiagnostic> Note);
- bool RequireCompleteType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD);
- bool RequireCompleteType(SourceLocation Loc, QualType T,
- unsigned DiagID);
-
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- const CXXScopeSpec &SS, QualType T);
-
- QualType BuildTypeofExprType(Expr *E);
- QualType BuildDecltypeType(Expr *E);
-
- //===--------------------------------------------------------------------===//
- // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
- //
-
- /// getDeclName - Return a pretty name for the specified decl if possible, or
- /// an empty string if not. This is used for pretty crash reporting.
- virtual std::string getDeclName(DeclPtrTy D);
-
- DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
-
- virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec *SS,
- bool isClassName = false,
- TypeTy *ObjectType = 0);
- virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
- virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
- SourceLocation IILoc,
- Scope *S,
- CXXScopeSpec *SS,
- TypeTy *&SuggestedType);
-
- virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
- return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
- }
-
- DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParameterLists,
- bool IsFunctionDefinition);
- void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
- const LookupResult &Previous,
- Scope *S);
- void DiagnoseFunctionSpecifiers(Declarator& D);
- void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
- void CheckShadow(Scope *S, VarDecl *D);
- NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, TypeSourceInfo *TInfo,
- LookupResult &Previous, bool &Redeclaration);
- NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, TypeSourceInfo *TInfo,
- LookupResult &Previous,
- MultiTemplateParamsArg TemplateParamLists,
- bool &Redeclaration);
- void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
- bool &Redeclaration);
- NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, TypeSourceInfo *TInfo,
- LookupResult &Previous,
- MultiTemplateParamsArg TemplateParamLists,
- bool IsFunctionDefinition,
- bool &Redeclaration);
- void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
- void CheckFunctionDeclaration(Scope *S,
- FunctionDecl *NewFD, LookupResult &Previous,
- bool IsExplicitSpecialization,
- bool &Redeclaration,
- bool &OverloadableAttrRequired);
- void CheckMain(FunctionDecl *FD);
- virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D);
- ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
- SourceLocation Loc,
- QualType T);
- ParmVarDecl *CheckParameter(DeclContext *DC,
- TypeSourceInfo *TSInfo, QualType T,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- VarDecl::StorageClass StorageClass,
- VarDecl::StorageClass StorageClassAsWritten);
- virtual void ActOnParamDefaultArgument(DeclPtrTy param,
- SourceLocation EqualLoc,
- ExprArg defarg);
- virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
- SourceLocation EqualLoc,
- SourceLocation ArgLoc);
- virtual void ActOnParamDefaultArgumentError(DeclPtrTy param);
- bool SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
- SourceLocation EqualLoc);
-
-
- // Contains the locations of the beginning of unparsed default
- // argument locations.
- llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
-
- virtual void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init);
- void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
- void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
- virtual void ActOnInitializerError(DeclPtrTy Dcl);
- virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
- virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
- DeclPtrTy *Group,
- unsigned NumDecls);
- virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
- SourceLocation LocAfterDecls);
- virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D);
- virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D);
- virtual void ActOnStartOfObjCMethodDef(Scope *S, DeclPtrTy D);
-
- virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body);
- DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body,
- bool IsInstantiation);
-
- /// \brief Diagnose any unused parameters in the given sequence of
- /// ParmVarDecl pointers.
- template<typename InputIterator>
- void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
- if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) ==
- Diagnostic::Ignored)
- return;
-
- // Don't diagnose unused-parameter errors in template instantiations; we
- // will already have done so in the template itself.
- if (!ActiveTemplateInstantiations.empty())
- return;
-
- for (; Param != ParamEnd; ++Param) {
- if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
- !(*Param)->template hasAttr<UnusedAttr>()) {
- Diag((*Param)->getLocation(), diag::warn_unused_parameter)
- << (*Param)->getDeclName();
- }
- }
- }
-
- void DiagnoseInvalidJumps(Stmt *Body);
- virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
-
- /// Scope actions.
- virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
- virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
-
- /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
- /// no declarator (e.g. "struct foo;") is parsed.
- virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
- DeclSpec &DS);
-
- virtual DeclPtrTy BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
- AccessSpecifier AS,
- RecordDecl *Record);
-
- bool isAcceptableTagRedeclaration(const TagDecl *Previous,
- TagDecl::TagKind NewTag,
- SourceLocation NewTagLoc,
- const IdentifierInfo &Name);
-
- virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr, AccessSpecifier AS,
- MultiTemplateParamsArg TemplateParameterLists,
- bool &OwnedDecl, bool &IsDependent);
-
- virtual TypeResult ActOnDependentTag(Scope *S,
- unsigned TagSpec,
- TagUseKind TUK,
- const CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation TagLoc,
- SourceLocation NameLoc);
-
- virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
- IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclPtrTy> &Decls);
- virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
- SourceLocation DeclStart,
- Declarator &D, ExprTy *BitfieldWidth);
-
- FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
- AccessSpecifier AS);
-
- FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
- TypeSourceInfo *TInfo,
- RecordDecl *Record, SourceLocation Loc,
- bool Mutable, Expr *BitfieldWidth,
- SourceLocation TSSL,
- AccessSpecifier AS, NamedDecl *PrevDecl,
- Declarator *D = 0);
-
- enum CXXSpecialMember {
- CXXInvalid = -1,
- CXXConstructor = 0,
- CXXCopyConstructor = 1,
- CXXCopyAssignment = 2,
- CXXDestructor = 3
- };
- void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
- CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
-
- virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
- DeclPtrTy IntfDecl,
- Declarator &D, ExprTy *BitfieldWidth,
- tok::ObjCKeywordKind visibility);
-
- // This is used for both record definitions and ObjC interface declarations.
- virtual void ActOnFields(Scope* S,
- SourceLocation RecLoc, DeclPtrTy TagDecl,
- DeclPtrTy *Fields, unsigned NumFields,
- SourceLocation LBrac, SourceLocation RBrac,
- AttributeList *AttrList);
-
- /// ActOnTagStartDefinition - Invoked when we have entered the
- /// scope of a tag's definition (e.g., for an enumeration, class,
- /// struct, or union).
- virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl);
-
- /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
- /// C++ record definition's base-specifiers clause and are starting its
- /// member declarations.
- virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl,
- SourceLocation LBraceLoc);
-
- /// ActOnTagFinishDefinition - Invoked once we have finished parsing
- /// the definition of a tag (enumeration, class, struct, or union).
- virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
- SourceLocation RBraceLoc);
-
- /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
- /// error parsing the definition of a tag.
- virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl);
-
- EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
- EnumConstantDecl *LastEnumConst,
- SourceLocation IdLoc,
- IdentifierInfo *Id,
- ExprArg val);
-
- virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
- DeclPtrTy LastEnumConstant,
- SourceLocation IdLoc, IdentifierInfo *Id,
- SourceLocation EqualLoc, ExprTy *Val);
- virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
- SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
- DeclPtrTy *Elements, unsigned NumElements,
- Scope *S, AttributeList *Attr);
-
- DeclContext *getContainingDC(DeclContext *DC);
-
- /// Set the current declaration context until it gets popped.
- void PushDeclContext(Scope *S, DeclContext *DC);
- void PopDeclContext();
-
- /// EnterDeclaratorContext - Used when we must lookup names in the context
- /// of a declarator's nested name specifier.
- void EnterDeclaratorContext(Scope *S, DeclContext *DC);
- void ExitDeclaratorContext(Scope *S);
-
- DeclContext *getFunctionLevelDeclContext();
-
- /// getCurFunctionDecl - If inside of a function body, this returns a pointer
- /// to the function decl for the function being parsed. If we're currently
- /// in a 'block', this returns the containing context.
- FunctionDecl *getCurFunctionDecl();
-
- /// getCurMethodDecl - If inside of a method body, this returns a pointer to
- /// the method decl for the method being parsed. If we're currently
- /// in a 'block', this returns the containing context.
- ObjCMethodDecl *getCurMethodDecl();
-
- /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
- /// or C function we're in, otherwise return null. If we're currently
- /// in a 'block', this returns the containing context.
- NamedDecl *getCurFunctionOrMethodDecl();
-
- /// Add this decl to the scope shadowed decl chains.
- void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
-
- /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
- /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
- /// true if 'D' belongs to the given declaration context.
- bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0);
-
- /// Finds the scope corresponding to the given decl context, if it
- /// happens to be an enclosing scope. Otherwise return NULL.
- Scope *getScopeForDeclContext(Scope *S, DeclContext *DC) {
- DeclContext *TargetDC = DC->getPrimaryContext();
- do {
- if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
- if (ScopeDC->getPrimaryContext() == TargetDC)
- return S;
- } while ((S = S->getParent()));
-
- return NULL;
- }
-
- /// Subroutines of ActOnDeclarator().
- TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
- TypeSourceInfo *TInfo);
- void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
- bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
- bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
- void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
- bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
-
- // AssignmentAction - This is used by all the assignment diagnostic functions
- // to represent what is actually causing the operation
- enum AssignmentAction {
- AA_Assigning,
- AA_Passing,
- AA_Returning,
- AA_Converting,
- AA_Initializing,
- AA_Sending,
- AA_Casting
- };
-
- /// C++ Overloading.
- enum OverloadKind {
- /// This is a legitimate overload: the existing declarations are
- /// functions or function templates with different signatures.
- Ovl_Overload,
-
- /// This is not an overload because the signature exactly matches
- /// an existing declaration.
- Ovl_Match,
-
- /// This is not an overload because the lookup results contain a
- /// non-function.
- Ovl_NonFunction
- };
- OverloadKind CheckOverload(Scope *S,
- FunctionDecl *New,
- const LookupResult &OldDecls,
- NamedDecl *&OldDecl,
- bool IsForUsingDecl);
- bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);
-
- bool TryImplicitConversion(InitializationSequence &Sequence,
- const InitializedEntity &Entity,
- Expr *From,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution);
-
- ImplicitConversionSequence
- TryImplicitConversion(Expr* From, QualType ToType,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution);
- bool IsStandardConversion(Expr *From, QualType ToType,
- bool InOverloadResolution,
- StandardConversionSequence& SCS);
- bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
- bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
- bool IsComplexPromotion(QualType FromType, QualType ToType);
- bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
- bool InOverloadResolution,
- QualType& ConvertedType, bool &IncompatibleObjC);
- bool isObjCPointerConversion(QualType FromType, QualType ToType,
- QualType& ConvertedType, bool &IncompatibleObjC);
- bool FunctionArgTypesAreEqual (FunctionProtoType* OldType,
- FunctionProtoType* NewType);
-
- bool CheckPointerConversion(Expr *From, QualType ToType,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray& BasePath,
- bool IgnoreBaseAccess);
- bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
- bool InOverloadResolution,
- QualType &ConvertedType);
- bool CheckMemberPointerConversion(Expr *From, QualType ToType,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath,
- bool IgnoreBaseAccess);
- bool IsQualificationConversion(QualType FromType, QualType ToType);
- OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
- UserDefinedConversionSequence& User,
- OverloadCandidateSet& Conversions,
- bool AllowExplicit);
- bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
-
-
- ImplicitConversionSequence::CompareKind
- CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
- const ImplicitConversionSequence& ICS2);
-
- ImplicitConversionSequence::CompareKind
- CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
- ImplicitConversionSequence::CompareKind
- CompareQualificationConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
- ImplicitConversionSequence::CompareKind
- CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2);
-
- OwningExprResult PerformCopyInitialization(const InitializedEntity &Entity,
- SourceLocation EqualLoc,
- OwningExprResult Init);
- ImplicitConversionSequence
- TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
- CXXRecordDecl *ActingContext);
- bool PerformObjectArgumentInitialization(Expr *&From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- CXXMethodDecl *Method);
-
- ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
- bool PerformContextuallyConvertToBool(Expr *&From);
-
- ImplicitConversionSequence TryContextuallyConvertToObjCId(Expr *From);
- bool PerformContextuallyConvertToObjCId(Expr *&From);
-
- OwningExprResult
- ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
- const PartialDiagnostic &NotIntDiag,
- const PartialDiagnostic &IncompleteDiag,
- const PartialDiagnostic &ExplicitConvDiag,
- const PartialDiagnostic &ExplicitConvNote,
- const PartialDiagnostic &AmbigDiag,
- const PartialDiagnostic &AmbigNote,
- const PartialDiagnostic &ConvDiag);
-
- bool PerformObjectMemberConversion(Expr *&From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- NamedDecl *Member);
-
- // Members have to be NamespaceDecl* or TranslationUnitDecl*.
- // TODO: make this is a typesafe union.
- typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet;
- typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
-
- void AddOverloadCandidate(NamedDecl *Function,
- DeclAccessPair FoundDecl,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet &CandidateSet);
-
- void AddOverloadCandidate(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false);
- void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
- void AddMethodCandidate(DeclAccessPair FoundDecl,
- QualType ObjectType,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversion = false);
- void AddMethodCandidate(CXXMethodDecl *Method,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext, QualType ObjectType,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
- void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- QualType ObjectType,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
- void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
- DeclAccessPair FoundDecl,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
- void AddConversionCandidate(CXXConversionDecl *Conversion,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- Expr *From, QualType ToType,
- OverloadCandidateSet& CandidateSet);
- void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- Expr *From, QualType ToType,
- OverloadCandidateSet &CandidateSet);
- void AddSurrogateCandidate(CXXConversionDecl *Conversion,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext,
- const FunctionProtoType *Proto,
- QualType ObjectTy, Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet);
- void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
- SourceLocation OpLoc,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- SourceRange OpRange = SourceRange());
- void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet,
- bool IsAssignmentOperator = false,
- unsigned NumContextualBoolArguments = 0);
- void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
- SourceLocation OpLoc,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet);
- void AddArgumentDependentLookupCandidates(DeclarationName Name,
- bool Operator,
- Expr **Args, unsigned NumArgs,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- OverloadCandidateSet& CandidateSet,
- bool PartialOverloading = false);
- bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2,
- SourceLocation Loc);
- OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
- SourceLocation Loc,
- OverloadCandidateSet::iterator& Best);
-
- enum OverloadCandidateDisplayKind {
- /// Requests that all candidates be shown. Viable candidates will
- /// be printed first.
- OCD_AllCandidates,
-
- /// Requests that only viable candidates be shown.
- OCD_ViableCandidates
- };
- void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
- OverloadCandidateDisplayKind OCD,
- Expr **Args, unsigned NumArgs,
- const char *Opc = 0,
- SourceLocation Loc = SourceLocation());
-
- void NoteOverloadCandidate(FunctionDecl *Fn);
- void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
- SourceLocation CaretLoc,
- const PartialDiagnostic &PDiag);
-
- FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
- bool Complain,
- DeclAccessPair &Found);
- FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From);
-
- Expr *FixOverloadedFunctionReference(Expr *E,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
- OwningExprResult FixOverloadedFunctionReference(OwningExprResult,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
-
- void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
- Expr **Args, unsigned NumArgs,
- OverloadCandidateSet &CandidateSet,
- bool PartialOverloading = false);
-
- OwningExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
- UnresolvedLookupExpr *ULE,
- SourceLocation LParenLoc,
- Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- OwningExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
- unsigned Opc,
- const UnresolvedSetImpl &Fns,
- ExprArg input);
-
- OwningExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
- unsigned Opc,
- const UnresolvedSetImpl &Fns,
- Expr *LHS, Expr *RHS);
-
- OwningExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
- SourceLocation RLoc,
- ExprArg Base,ExprArg Idx);
-
- OwningExprResult
- BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
- SourceLocation LParenLoc, Expr **Args,
- unsigned NumArgs, SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
- ExprResult
- BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
- Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- OwningExprResult BuildOverloadedArrowExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc);
-
- /// CheckCallReturnType - Checks that a call expression's return type is
- /// complete. Returns true on failure. The location passed in is the location
- /// that best represents the call.
- bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
- CallExpr *CE, FunctionDecl *FD);
-
- /// Helpers for dealing with blocks and functions.
- bool CheckParmsForFunctionDef(FunctionDecl *FD);
- void CheckCXXDefaultArguments(FunctionDecl *FD);
- void CheckExtraCXXDefaultArguments(Declarator &D);
- Scope *getNonFieldDeclScope(Scope *S);
-
- /// \name Name lookup
- ///
- /// These routines provide name lookup that is used during semantic
- /// analysis to resolve the various kinds of names (identifiers,
- /// overloaded operator names, constructor names, etc.) into zero or
- /// more declarations within a particular scope. The major entry
- /// points are LookupName, which performs unqualified name lookup,
- /// and LookupQualifiedName, which performs qualified name lookup.
- ///
- /// All name lookup is performed based on some specific criteria,
- /// which specify what names will be visible to name lookup and how
- /// far name lookup should work. These criteria are important both
- /// for capturing language semantics (certain lookups will ignore
- /// certain names, for example) and for performance, since name
- /// lookup is often a bottleneck in the compilation of C++. Name
- /// lookup criteria is specified via the LookupCriteria enumeration.
- ///
- /// The results of name lookup can vary based on the kind of name
- /// lookup performed, the current language, and the translation
- /// unit. In C, for example, name lookup will either return nothing
- /// (no entity found) or a single declaration. In C++, name lookup
- /// can additionally refer to a set of overloaded functions or
- /// result in an ambiguity. All of the possible results of name
- /// lookup are captured by the LookupResult class, which provides
- /// the ability to distinguish among them.
- //@{
-
- /// @brief Describes the kind of name lookup to perform.
- enum LookupNameKind {
- /// Ordinary name lookup, which finds ordinary names (functions,
- /// variables, typedefs, etc.) in C and most kinds of names
- /// (functions, variables, members, types, etc.) in C++.
- LookupOrdinaryName = 0,
- /// Tag name lookup, which finds the names of enums, classes,
- /// structs, and unions.
- LookupTagName,
- /// Member name lookup, which finds the names of
- /// class/struct/union members.
- LookupMemberName,
- // Look up of an operator name (e.g., operator+) for use with
- // operator overloading. This lookup is similar to ordinary name
- // lookup, but will ignore any declarations that are class
- // members.
- LookupOperatorName,
- /// Look up of a name that precedes the '::' scope resolution
- /// operator in C++. This lookup completely ignores operator, object,
- /// function, and enumerator names (C++ [basic.lookup.qual]p1).
- LookupNestedNameSpecifierName,
- /// Look up a namespace name within a C++ using directive or
- /// namespace alias definition, ignoring non-namespace names (C++
- /// [basic.lookup.udir]p1).
- LookupNamespaceName,
- /// Look up all declarations in a scope with the given name,
- /// including resolved using declarations. This is appropriate
- /// for checking redeclarations for a using declaration.
- LookupUsingDeclName,
- /// Look up an ordinary name that is going to be redeclared as a
- /// name with linkage. This lookup ignores any declarations that
- /// are outside of the current scope unless they have linkage. See
- /// C99 6.2.2p4-5 and C++ [basic.link]p6.
- LookupRedeclarationWithLinkage,
- /// Look up the name of an Objective-C protocol.
- LookupObjCProtocolName
- };
-
- /// \brief Specifies whether (or how) name lookup is being performed for a
- /// redeclaration (vs. a reference).
- enum RedeclarationKind {
- /// \brief The lookup is a reference to this name that is not for the
- /// purpose of redeclaring the name.
- NotForRedeclaration = 0,
- /// \brief The lookup results will be used for redeclaration of a name,
- /// if an entity by that name already exists.
- ForRedeclaration
- };
-
-private:
- bool CppLookupName(LookupResult &R, Scope *S);
-
-public:
- /// \brief Look up a name, looking for a single declaration. Return
- /// null if the results were absent, ambiguous, or overloaded.
- ///
- /// It is preferable to use the elaborated form and explicitly handle
- /// ambiguity and overloaded.
- NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
- SourceLocation Loc,
- LookupNameKind NameKind,
- RedeclarationKind Redecl
- = NotForRedeclaration);
- bool LookupName(LookupResult &R, Scope *S,
- bool AllowBuiltinCreation = false);
- bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
- bool InUnqualifiedLookup = false);
- bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
- bool AllowBuiltinCreation = false,
- bool EnteringContext = false);
- ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc);
-
- void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
- QualType T1, QualType T2,
- UnresolvedSetImpl &Functions);
- DeclContext::lookup_result LookupConstructors(CXXRecordDecl *Class);
- CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
-
- void ArgumentDependentLookup(DeclarationName Name, bool Operator,
- Expr **Args, unsigned NumArgs,
- ADLResult &Functions);
-
- void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer);
- void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer);
-
- /// \brief The context in which typo-correction occurs.
- ///
- /// The typo-correction context affects which keywords (if any) are
- /// considered when trying to correct for typos.
- enum CorrectTypoContext {
- /// \brief An unknown context, where any keyword might be valid.
- CTC_Unknown,
- /// \brief A context where no keywords are used (e.g. we expect an actual
- /// name).
- CTC_NoKeywords,
- /// \brief A context where we're correcting a type name.
- CTC_Type,
- /// \brief An expression context.
- CTC_Expression,
- /// \brief A type cast, or anything else that can be followed by a '<'.
- CTC_CXXCasts,
- /// \brief A member lookup context.
- CTC_MemberLookup,
- /// \brief The receiver of an Objective-C message send within an
- /// Objective-C method where 'super' is a valid keyword.
- CTC_ObjCMessageReceiver
- };
-
- DeclarationName CorrectTypo(LookupResult &R, Scope *S, CXXScopeSpec *SS,
- DeclContext *MemberContext = 0,
- bool EnteringContext = false,
- CorrectTypoContext CTC = CTC_Unknown,
- const ObjCObjectPointerType *OPT = 0);
-
- void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
- AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses);
-
- bool DiagnoseAmbiguousLookup(LookupResult &Result);
- //@}
-
- ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
- SourceLocation IdLoc,
- bool TypoCorrection = false);
- NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
- Scope *S, bool ForRedeclaration,
- SourceLocation Loc);
- NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
- Scope *S);
- void AddKnownFunctionAttributes(FunctionDecl *FD);
-
- // More parsing and symbol table subroutines.
-
- // Decl attributes - this routine is the top level dispatcher.
- void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
- void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL);
-
- void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
- bool &IncompleteImpl, unsigned DiagID);
- void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
- ObjCMethodDecl *IntfMethod);
-
- bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
- ObjCInterfaceDecl *IDecl);
-
- /// CheckProtocolMethodDefs - This routine checks unimplemented
- /// methods declared in protocol, and those referenced by it.
- /// \param IDecl - Used for checking for methods which may have been
- /// inherited.
- void CheckProtocolMethodDefs(SourceLocation ImpLoc,
- ObjCProtocolDecl *PDecl,
- bool& IncompleteImpl,
- const llvm::DenseSet<Selector> &InsMap,
- const llvm::DenseSet<Selector> &ClsMap,
- ObjCContainerDecl *CDecl);
-
- /// CheckImplementationIvars - This routine checks if the instance variables
- /// listed in the implelementation match those listed in the interface.
- void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
- ObjCIvarDecl **Fields, unsigned nIvars,
- SourceLocation Loc);
-
- /// ImplMethodsVsClassMethods - This is main routine to warn if any method
- /// remains unimplemented in the class or category @implementation.
- void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl,
- bool IncompleteImpl = false);
-
- /// DiagnoseUnimplementedProperties - This routine warns on those properties
- /// which must be implemented by this implementation.
- void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl *CDecl,
- const llvm::DenseSet<Selector>& InsMap);
-
- /// DefaultSynthesizeProperties - This routine default synthesizes all
- /// properties which must be synthesized in class's @implementation.
- void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
- ObjCInterfaceDecl *IDecl);
-
- /// CollectImmediateProperties - This routine collects all properties in
- /// the class and its conforming protocols; but not those it its super class.
- void CollectImmediateProperties(ObjCContainerDecl *CDecl,
- llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
- llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
-
-
- /// LookupPropertyDecl - Looks up a property in the current class and all
- /// its protocols.
- ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl,
- IdentifierInfo *II);
-
- /// Called by ActOnProperty to handle @property declarations in
- //// class extensions.
- DeclPtrTy HandlePropertyInClassExtension(Scope *S,
- ObjCCategoryDecl *CDecl,
- SourceLocation AtLoc,
- FieldDeclarator &FD,
- Selector GetterSel,
- Selector SetterSel,
- const bool isAssign,
- const bool isReadWrite,
- const unsigned Attributes,
- bool *isOverridingProperty,
- TypeSourceInfo *T,
- tok::ObjCKeywordKind MethodImplKind);
-
- /// Called by ActOnProperty and HandlePropertyInClassExtension to
- /// handle creating the ObjcPropertyDecl for a category or @interface.
- ObjCPropertyDecl *CreatePropertyDecl(Scope *S,
- ObjCContainerDecl *CDecl,
- SourceLocation AtLoc,
- FieldDeclarator &FD,
- Selector GetterSel,
- Selector SetterSel,
- const bool isAssign,
- const bool isReadWrite,
- const unsigned Attributes,
- TypeSourceInfo *T,
- tok::ObjCKeywordKind MethodImplKind,
- DeclContext *lexicalDC = 0);
-
- /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
- /// warning) when atomic property has one but not the other user-declared
- /// setter or getter.
- void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl);
-
- void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
-
- /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
- /// true, or false, accordingly.
- bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
- const ObjCMethodDecl *PrevMethod,
- bool matchBasedOnSizeAndAlignment = false);
-
- /// MatchAllMethodDeclarations - Check methods declaraed in interface or
- /// or protocol against those declared in their implementations.
- void MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
- const llvm::DenseSet<Selector> &ClsMap,
- llvm::DenseSet<Selector> &InsMapSeen,
- llvm::DenseSet<Selector> &ClsMapSeen,
- ObjCImplDecl* IMPDecl,
- ObjCContainerDecl* IDecl,
- bool &IncompleteImpl,
- bool ImmediateClass);
-
- /// AddInstanceMethodToGlobalPool - All instance methods in a translation
- /// unit are added to a global pool. This allows us to efficiently associate
- /// a selector with a method declaraation for purposes of typechecking
- /// messages sent to "id" (where the class of the object is unknown).
- void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
-
- /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
- /// there are multiple signatures.
- ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
- bool warn=true);
-
- /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
- /// there are multiple signatures.
- ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R);
-
- /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
- void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
-
- /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
- /// initialization.
- void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
- llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
- //===--------------------------------------------------------------------===//
- // Statement Parsing Callbacks: SemaStmt.cpp.
-public:
- virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr);
-
- virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc);
- virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
- MultiStmtArg Elts,
- bool isStmtExpr);
- virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
- SourceLocation StartLoc,
- SourceLocation EndLoc);
- virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
- virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
- SourceLocation DotDotDotLoc, ExprArg RHSVal,
- SourceLocation ColonLoc);
- virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt);
-
- virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
- SourceLocation ColonLoc,
- StmtArg SubStmt, Scope *CurScope);
- virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
- IdentifierInfo *II,
- SourceLocation ColonLoc,
- StmtArg SubStmt);
- virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
- FullExprArg CondVal, DeclPtrTy CondVar,
- StmtArg ThenVal,
- SourceLocation ElseLoc, StmtArg ElseVal);
- virtual OwningStmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
- ExprArg Cond,
- DeclPtrTy CondVar);
- virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
- StmtArg Switch, StmtArg Body);
- virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
- FullExprArg Cond,
- DeclPtrTy CondVar, StmtArg Body);
- virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
- SourceLocation WhileLoc,
- SourceLocation CondLParen, ExprArg Cond,
- SourceLocation CondRParen);
-
- virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtArg First, FullExprArg Second,
- DeclPtrTy SecondVar,
- FullExprArg Third,
- SourceLocation RParenLoc,
- StmtArg Body);
- virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
- SourceLocation LParenLoc,
- StmtArg First, ExprArg Second,
- SourceLocation RParenLoc, StmtArg Body);
-
- virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
- IdentifierInfo *LabelII);
- virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
- SourceLocation StarLoc,
- ExprArg DestExp);
- virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
- Scope *CurScope);
- virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
- Scope *CurScope);
-
- virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
- ExprArg RetValExp);
- OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
- Expr *RetValExp);
-
- virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
- bool IsSimple,
- bool IsVolatile,
- unsigned NumOutputs,
- unsigned NumInputs,
- IdentifierInfo **Names,
- MultiExprArg Constraints,
- MultiExprArg Exprs,
- ExprArg AsmString,
- MultiExprArg Clobbers,
- SourceLocation RParenLoc,
- bool MSAsm = false);
-
-
- VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
- IdentifierInfo *Name, SourceLocation NameLoc,
- bool Invalid = false);
-
- virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D);
-
- virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen,
- DeclPtrTy Parm, StmtArg Body);
-
- virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
- StmtArg Body);
-
- virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtArg Try,
- MultiStmtArg Catch,
- StmtArg Finally);
-
- virtual OwningStmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc,
- ExprArg Throw);
- virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
- ExprArg Throw,
- Scope *CurScope);
- virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
- ExprArg SynchExpr,
- StmtArg SynchBody);
-
- VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
- TypeSourceInfo *TInfo,
- IdentifierInfo *Name,
- SourceLocation Loc,
- SourceRange Range);
- virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D);
-
- virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
- DeclPtrTy ExDecl,
- StmtArg HandlerBlock);
- virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
- StmtArg TryBlock,
- MultiStmtArg Handlers);
- void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
-
- /// DiagnoseUnusedExprResult - If the statement passed in is an expression
- /// whose result is unused, warn.
- void DiagnoseUnusedExprResult(const Stmt *S);
- void DiagnoseUnusedDecl(const NamedDecl *ND);
-
- ParsingDeclStackState PushParsingDeclaration();
- void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D);
- void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc);
-
- void HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, Decl *Ctx);
-
- //===--------------------------------------------------------------------===//
- // Expression Parsing Callbacks: SemaExpr.cpp.
-
- bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
- bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
- ObjCMethodDecl *Getter,
- SourceLocation Loc);
- void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
- Expr **Args, unsigned NumArgs);
-
- virtual void
- PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
-
- virtual void PopExpressionEvaluationContext();
-
- void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
- void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
- bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
-
- // Primary Expressions.
- virtual SourceRange getExprRange(ExprTy *E) const;
-
- virtual OwningExprResult ActOnIdExpression(Scope *S,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- bool HasTrailingLParen,
- bool IsAddressOfOperand);
-
- bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- CorrectTypoContext CTC = CTC_Unknown);
-
- OwningExprResult LookupInObjCMethod(LookupResult &R,
- Scope *S,
- IdentifierInfo *II,
- bool AllowBuiltinCreation=false);
-
- OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
- bool isAddressOfOperand,
- const TemplateArgumentListInfo *TemplateArgs);
-
- OwningExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
- SourceLocation Loc,
- const CXXScopeSpec *SS = 0);
- VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
- llvm::SmallVectorImpl<FieldDecl *> &Path);
- OwningExprResult
- BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
- FieldDecl *Field,
- Expr *BaseObjectExpr = 0,
- SourceLocation OpLoc = SourceLocation());
- OwningExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs);
- OwningExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- bool IsDefiniteInstance);
- bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
- const LookupResult &R,
- bool HasTrailingLParen);
-
- OwningExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc);
- OwningExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
- const TemplateArgumentListInfo *TemplateArgs);
-
- OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- bool ADL);
- OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
- SourceLocation Loc,
- NamedDecl *D);
-
- virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
- tok::TokenKind Kind);
- virtual OwningExprResult ActOnNumericConstant(const Token &);
- virtual OwningExprResult ActOnCharacterConstant(const Token &);
- virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
- ExprArg Val);
- virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
- SourceLocation R,
- MultiExprArg Val,
- TypeTy *TypeOfCast=0);
-
- /// ActOnStringLiteral - The specified tokens were lexed as pasted string
- /// fragments (e.g. "foo" "bar" L"baz").
- virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
- unsigned NumToks);
-
- // Binary/Unary Operators. 'Tok' is the token for the operator.
- OwningExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
- unsigned OpcIn,
- ExprArg InputArg);
- OwningExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
- UnaryOperator::Opcode Opc, ExprArg input);
- virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, ExprArg Input);
-
- OwningExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T,
- SourceLocation OpLoc,
- bool isSizeOf, SourceRange R);
- OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
- bool isSizeOf, SourceRange R);
- virtual OwningExprResult
- ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
- void *TyOrEx, const SourceRange &ArgRange);
-
- bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R);
- bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
- const SourceRange &R, bool isSizeof);
-
- virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Kind,
- ExprArg Input);
-
- virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
- SourceLocation LLoc,
- ExprArg Idx,
- SourceLocation RLoc);
- OwningExprResult CreateBuiltinArraySubscriptExpr(ExprArg Base,
- SourceLocation LLoc,
- ExprArg Idx,
- SourceLocation RLoc);
-
- OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
- QualType BaseType,
- SourceLocation OpLoc,
- bool IsArrow,
- CXXScopeSpec &SS,
- NamedDecl *FirstQualifierInScope,
- DeclarationName Name,
- SourceLocation NameLoc,
- const TemplateArgumentListInfo *TemplateArgs);
-
- OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
- QualType BaseType,
- SourceLocation OpLoc, bool IsArrow,
- const CXXScopeSpec &SS,
- NamedDecl *FirstQualifierInScope,
- LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs,
- bool SuppressQualifierCheck = false);
-
- OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
- bool &IsArrow, SourceLocation OpLoc,
- CXXScopeSpec &SS,
- DeclPtrTy ObjCImpDecl,
- bool HasTemplateArgs);
-
- bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
- const CXXScopeSpec &SS,
- const LookupResult &R);
-
- OwningExprResult ActOnDependentMemberExpr(ExprArg Base,
- QualType BaseType,
- bool IsArrow,
- SourceLocation OpLoc,
- const CXXScopeSpec &SS,
- NamedDecl *FirstQualifierInScope,
- DeclarationName Name,
- SourceLocation NameLoc,
- const TemplateArgumentListInfo *TemplateArgs);
-
- virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- UnqualifiedId &Member,
- DeclPtrTy ObjCImpDecl,
- bool HasTrailingLParen);
-
- virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
- bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
- FunctionDecl *FDecl,
- const FunctionProtoType *Proto,
- Expr **Args, unsigned NumArgs,
- SourceLocation RParenLoc);
-
- /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
- /// This provides the location of the left/right parens and a list of comma
- /// locations.
- virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
- SourceLocation LParenLoc,
- MultiExprArg Args,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
- OwningExprResult BuildResolvedCallExpr(Expr *Fn,
- NamedDecl *NDecl,
- SourceLocation LParenLoc,
- Expr **Args, unsigned NumArgs,
- SourceLocation RParenLoc);
-
- virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
- TypeTy *Ty, SourceLocation RParenLoc,
- ExprArg Op);
- OwningExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
- TypeSourceInfo *Ty,
- SourceLocation RParenLoc,
- ExprArg Op);
-
- virtual bool TypeIsVectorType(TypeTy *Ty) {
- return GetTypeFromParser(Ty)->isVectorType();
- }
-
- OwningExprResult MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg ME);
- OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
- SourceLocation RParenLoc, ExprArg E,
- TypeSourceInfo *TInfo);
-
- virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
- TypeTy *Ty,
- SourceLocation RParenLoc,
- ExprArg Op);
-
- OwningExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
- TypeSourceInfo *TInfo,
- SourceLocation RParenLoc,
- ExprArg InitExpr);
-
- virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
- MultiExprArg InitList,
- SourceLocation RParenLoc);
-
- virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
- SourceLocation Loc,
- bool GNUSyntax,
- OwningExprResult Init);
-
- virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
- tok::TokenKind Kind,
- ExprArg LHS, ExprArg RHS);
- OwningExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
- BinaryOperator::Opcode Opc,
- Expr *lhs, Expr *rhs);
- OwningExprResult CreateBuiltinBinOp(SourceLocation TokLoc,
- unsigned Opc, Expr *lhs, Expr *rhs);
-
- /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
- /// in the case of a the GNU conditional expr extension.
- virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
- SourceLocation ColonLoc,
- ExprArg Cond, ExprArg LHS,
- ExprArg RHS);
-
- /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
- virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
- SourceLocation LabLoc,
- IdentifierInfo *LabelII);
-
- virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtArg SubStmt,
- SourceLocation RPLoc); // "({..})"
-
- /// __builtin_offsetof(type, a.b[123][456].c)
- OwningExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
- TypeSourceInfo *TInfo,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc);
- virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
- SourceLocation BuiltinLoc,
- SourceLocation TypeLoc,
- TypeTy *Arg1,
- OffsetOfComponent *CompPtr,
- unsigned NumComponents,
- SourceLocation RParenLoc);
-
- // __builtin_types_compatible_p(type1, type2)
- virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1, TypeTy *arg2,
- SourceLocation RPLoc);
-
- // __builtin_choose_expr(constExpr, expr1, expr2)
- virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprArg cond, ExprArg expr1,
- ExprArg expr2, SourceLocation RPLoc);
-
- // __builtin_va_arg(expr, type)
- virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
- ExprArg expr, TypeTy *type,
- SourceLocation RPLoc);
-
- // __null
- virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
-
- //===------------------------- "Block" Extension ------------------------===//
-
- /// ActOnBlockStart - This callback is invoked when a block literal is
- /// started.
- virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
-
- /// ActOnBlockArguments - This callback allows processing of block arguments.
- /// If there are no arguments, this is still invoked.
- virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope);
-
- /// ActOnBlockError - If there is an error parsing a block, this callback
- /// is invoked to pop the information about the block from the action impl.
- virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
-
- /// ActOnBlockStmtExpr - This is called when the body of a block statement
- /// literal was successfully completed. ^(int x){...}
- virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
- StmtArg Body, Scope *CurScope);
-
- //===---------------------------- C++ Features --------------------------===//
-
- // Act on C++ namespaces
- virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
- IdentifierInfo *Ident,
- SourceLocation LBrace,
- AttributeList *AttrList);
- virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace);
-
- NamespaceDecl *getStdNamespace();
- virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
- SourceLocation UsingLoc,
- SourceLocation NamespcLoc,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *NamespcName,
- AttributeList *AttrList);
-
- void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
-
- virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- IdentifierInfo *Ident);
-
- void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
- bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
- const LookupResult &PreviousDecls);
- UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
- NamedDecl *Target);
-
- bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
- bool isTypeName,
- const CXXScopeSpec &SS,
- SourceLocation NameLoc,
- const LookupResult &Previous);
- bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
- const CXXScopeSpec &SS,
- SourceLocation NameLoc);
-
- NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
- SourceLocation UsingLoc,
- CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- DeclarationName Name,
- AttributeList *AttrList,
- bool IsInstantiation,
- bool IsTypeName,
- SourceLocation TypenameLoc);
-
- virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
- AccessSpecifier AS,
- bool HasUsingKeyword,
- SourceLocation UsingLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- AttributeList *AttrList,
- bool IsTypeName,
- SourceLocation TypenameLoc);
-
- /// AddCXXDirectInitializerToDecl - This action is called immediately after
- /// ActOnDeclarator, when a C++ direct initializer is present.
- /// e.g: "int x(1);"
- virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- /// InitializeVarWithConstructor - Creates an CXXConstructExpr
- /// and sets it as the initializer for the the passed in VarDecl.
- bool InitializeVarWithConstructor(VarDecl *VD,
- CXXConstructorDecl *Constructor,
- MultiExprArg Exprs);
-
- /// BuildCXXConstructExpr - Creates a complete call to a constructor,
- /// including handling of its default argument expressions.
- OwningExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- CXXConstructorDecl *Constructor, MultiExprArg Exprs,
- bool RequiresZeroInit = false,
- CXXConstructExpr::ConstructionKind ConstructKind =
- CXXConstructExpr::CK_Complete);
-
- // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
- // the constructor can be elidable?
- OwningExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- CXXConstructorDecl *Constructor, bool Elidable,
- MultiExprArg Exprs, bool RequiresZeroInit = false,
- CXXConstructExpr::ConstructionKind ConstructKind =
- CXXConstructExpr::CK_Complete);
-
- /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
- /// the default expr if needed.
- OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
- FunctionDecl *FD,
- ParmVarDecl *Param);
-
- /// FinalizeVarWithDestructor - Prepare for calling destructor on the
- /// constructed variable.
- void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
-
- /// \brief Declare the implicit default constructor for the given class.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// default constructor will be added.
- ///
- /// \returns The implicitly-declared default constructor.
- CXXConstructorDecl *DeclareImplicitDefaultConstructor(
- CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitDefaultConstructor - Checks for feasibility of
- /// defining this constructor as the default constructor.
- void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
- CXXConstructorDecl *Constructor);
-
- /// \brief Declare the implicit destructor for the given class.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// destructor will be added.
- ///
- /// \returns The implicitly-declared destructor.
- CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitDestructor - Checks for feasibility of
- /// defining this destructor as the default destructor.
- void DefineImplicitDestructor(SourceLocation CurrentLocation,
- CXXDestructorDecl *Destructor);
-
- /// \brief Declare the implicit copy constructor for the given class.
- ///
- /// \param S The scope of the class, which may be NULL if this is a
- /// template instantiation.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// copy constructor will be added.
- ///
- /// \returns The implicitly-declared copy constructor.
- CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl);
-
- /// DefineImplicitCopyConstructor - Checks for feasibility of
- /// defining this constructor as the copy constructor.
- void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
- CXXConstructorDecl *Constructor,
- unsigned TypeQuals);
-
- /// \brief Declare the implicit copy assignment operator for the given class.
- ///
- /// \param S The scope of the class, which may be NULL if this is a
- /// template instantiation.
- ///
- /// \param ClassDecl The class declaration into which the implicit
- /// copy-assignment operator will be added.
- ///
- /// \returns The implicitly-declared copy assignment operator.
- CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
-
- /// \brief Defined an implicitly-declared copy assignment operator.
- void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
- CXXMethodDecl *MethodDecl);
-
- /// \brief Force the declaration of any implicitly-declared members of this
- /// class.
- void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
-
- /// MaybeBindToTemporary - If the passed in expression has a record type with
- /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
- /// it simply returns the passed in expression.
- OwningExprResult MaybeBindToTemporary(Expr *E);
-
- bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
- MultiExprArg ArgsPtr,
- SourceLocation Loc,
- ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
-
- virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec &SS,
- TypeTy *ObjectType,
- bool EnteringContext);
-
- /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
- virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
- tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc,
- TypeTy *Ty,
- SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc,
- ExprArg E,
- SourceLocation RParenLoc);
-
- OwningExprResult BuildCXXNamedCast(SourceLocation OpLoc,
- tok::TokenKind Kind,
- TypeSourceInfo *Ty,
- ExprArg E,
- SourceRange AngleBrackets,
- SourceRange Parens);
-
- OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- TypeSourceInfo *Operand,
- SourceLocation RParenLoc);
- OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
- SourceLocation TypeidLoc,
- ExprArg Operand,
- SourceLocation RParenLoc);
-
- /// ActOnCXXTypeid - Parse typeid( something ).
- virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
- SourceLocation LParenLoc, bool isType,
- void *TyOrExpr,
- SourceLocation RParenLoc);
-
- //// ActOnCXXThis - Parse 'this' pointer.
- virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc);
-
- /// ActOnCXXBoolLiteral - Parse {true,false} literals.
- virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
- tok::TokenKind Kind);
-
- /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
- virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
-
- //// ActOnCXXThrow - Parse throw expressions.
- virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc,
- ExprArg expr);
- bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E);
-
- /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
- /// Can be interpreted either as function-style casting ("int(x)")
- /// or class type construction ("ClassType(x,y,z)")
- /// or creation of a value-initialized type ("int()").
- virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
- TypeTy *TypeRep,
- SourceLocation LParenLoc,
- MultiExprArg Exprs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- /// ActOnCXXNew - Parsed a C++ 'new' expression.
- virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
- SourceLocation PlacementLParen,
- MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen,
- SourceRange TypeIdParens, Declarator &D,
- SourceLocation ConstructorLParen,
- MultiExprArg ConstructorArgs,
- SourceLocation ConstructorRParen);
- OwningExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
- SourceLocation PlacementLParen,
- MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen,
- SourceRange TypeIdParens,
- QualType AllocType,
- SourceLocation TypeLoc,
- SourceRange TypeRange,
- ExprArg ArraySize,
- SourceLocation ConstructorLParen,
- MultiExprArg ConstructorArgs,
- SourceLocation ConstructorRParen);
-
- bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
- SourceRange R);
- bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
- bool UseGlobal, QualType AllocType, bool IsArray,
- Expr **PlaceArgs, unsigned NumPlaceArgs,
- FunctionDecl *&OperatorNew,
- FunctionDecl *&OperatorDelete);
- bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
- DeclarationName Name, Expr** Args,
- unsigned NumArgs, DeclContext *Ctx,
- bool AllowMissing, FunctionDecl *&Operator);
- void DeclareGlobalNewDelete();
- void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
- QualType Argument,
- bool addMallocAttr = false);
-
- bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
- DeclarationName Name, FunctionDecl* &Operator);
-
- /// ActOnCXXDelete - Parsed a C++ 'delete' expression
- virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
- bool UseGlobal, bool ArrayForm,
- ExprArg Operand);
-
- virtual DeclResult ActOnCXXConditionDeclaration(Scope *S,
- Declarator &D);
- OwningExprResult CheckConditionVariable(VarDecl *ConditionVar,
- SourceLocation StmtLoc,
- bool ConvertToBoolean);
-
- /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
- /// pseudo-functions.
- virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
- SourceLocation KWLoc,
- SourceLocation LParen,
- TypeTy *Ty,
- SourceLocation RParen);
-
- virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
- ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- TypeTy *&ObjectType,
- bool &MayBePseudoDestructor);
-
- OwningExprResult DiagnoseDtorReference(SourceLocation NameLoc,
- ExprArg MemExpr);
-
- OwningExprResult BuildPseudoDestructorExpr(ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
- TypeSourceInfo *ScopeType,
- SourceLocation CCLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType,
- bool HasTrailingLParen);
-
- virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- UnqualifiedId &FirstTypeName,
- SourceLocation CCLoc,
- SourceLocation TildeLoc,
- UnqualifiedId &SecondTypeName,
- bool HasTrailingLParen);
-
- /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
- /// non-empty, will create a new CXXExprWithTemporaries expression.
- /// Otherwise, just returs the passed in expression.
- Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
- OwningExprResult MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr);
- FullExpr CreateFullExpr(Expr *SubExpr);
-
- virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
-
- // Marks SS invalid if it represents an incomplete type.
- bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
-
- DeclContext *computeDeclContext(QualType T);
- DeclContext *computeDeclContext(const CXXScopeSpec &SS,
- bool EnteringContext = false);
- bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
- CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
- bool isUnknownSpecialization(const CXXScopeSpec &SS);
-
- /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
- /// global scope ('::').
- virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
- SourceLocation CCLoc);
-
- bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
- NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
-
- virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
- SourceLocation IdLoc,
- IdentifierInfo &II,
- TypeTy *ObjectType);
-
- CXXScopeTy *BuildCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- QualType ObjectType,
- NamedDecl *ScopeLookupResult,
- bool EnteringContext,
- bool ErrorRecoveryLookup);
-
- virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
- CXXScopeSpec &SS,
- SourceLocation IdLoc,
- SourceLocation CCLoc,
- IdentifierInfo &II,
- TypeTy *ObjectType,
- bool EnteringContext);
-
- virtual bool IsInvalidUnlessNestedName(Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo &II,
- TypeTy *ObjectType,
- bool EnteringContext);
-
- /// ActOnCXXNestedNameSpecifier - Called during parsing of a
- /// nested-name-specifier that involves a template-id, e.g.,
- /// "foo::bar<int, float>::", and now we need to build a scope
- /// specifier. \p SS is empty or the previously parsed nested-name
- /// part ("foo::"), \p Type is the already-parsed class template
- /// specialization (or other template-id that names a type), \p
- /// TypeRange is the source range where the type is located, and \p
- /// CCLoc is the location of the trailing '::'.
- virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
- const CXXScopeSpec &SS,
- TypeTy *Type,
- SourceRange TypeRange,
- SourceLocation CCLoc);
-
- virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
- /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
- /// scope or nested-name-specifier) is parsed, part of a declarator-id.
- /// After this method is called, according to [C++ 3.4.3p3], names should be
- /// looked up in the declarator-id's scope, until the declarator is parsed and
- /// ActOnCXXExitDeclaratorScope is called.
- /// The 'SS' should be a non-empty valid CXXScopeSpec.
- virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS);
-
- /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
- /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
- /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
- /// Used to indicate that names should revert to being looked up in the
- /// defining scope.
- virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
- /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
- /// initializer for the declaration 'Dcl'.
- /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
- /// static data member of class X, names should be looked up in the scope of
- /// class X.
- virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl);
-
- /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
- /// initializer for the declaration 'Dcl'.
- virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl);
-
- // ParseObjCStringLiteral - Parse Objective-C string literals.
- virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
- ExprTy **Strings,
- unsigned NumStrings);
-
- Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
- TypeSourceInfo *EncodedTypeInfo,
- SourceLocation RParenLoc);
- CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp,
- NamedDecl *FoundDecl,
- CXXMethodDecl *Method);
-
- virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncodeLoc,
- SourceLocation LParenLoc,
- TypeTy *Ty,
- SourceLocation RParenLoc);
-
- // ParseObjCSelectorExpression - Build selector expression for @selector
- virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- // ParseObjCProtocolExpression - Build protocol expression for @protocol
- virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- //===--------------------------------------------------------------------===//
- // C++ Declarations
- //
- virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation LangLoc,
- llvm::StringRef Lang,
- SourceLocation LBraceLoc);
- virtual DeclPtrTy ActOnFinishLinkageSpecification(Scope *S,
- DeclPtrTy LinkageSpec,
- SourceLocation RBraceLoc);
-
-
- //===--------------------------------------------------------------------===//
- // C++ Classes
- //
- virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
- const CXXScopeSpec *SS);
-
- virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc,
- SourceLocation ColonLoc);
-
- virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
- Declarator &D,
- MultiTemplateParamsArg TemplateParameterLists,
- ExprTy *BitfieldWidth,
- ExprTy *Init, bool IsDefinition,
- bool Deleted = false);
-
- virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
- Scope *S,
- CXXScopeSpec &SS,
- IdentifierInfo *MemberOrBase,
- TypeTy *TemplateTypeTy,
- SourceLocation IdLoc,
- SourceLocation LParenLoc,
- ExprTy **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc);
-
- MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
- unsigned NumArgs, SourceLocation IdLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- MemInitResult BuildBaseInitializer(QualType BaseType,
- TypeSourceInfo *BaseTInfo,
- Expr **Args, unsigned NumArgs,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc,
- CXXRecordDecl *ClassDecl);
-
- bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
- CXXBaseOrMemberInitializer **Initializers,
- unsigned NumInitializers, bool AnyErrors);
-
- void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
-
-
- /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
- /// mark all the non-trivial destructors of its members and bases as
- /// referenced.
- void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
- CXXRecordDecl *Record);
-
- /// \brief The list of classes whose vtables have been used within
- /// this translation unit, and the source locations at which the
- /// first use occurred.
- llvm::SmallVector<std::pair<CXXRecordDecl *, SourceLocation>, 16>
- VTableUses;
-
- /// \brief The set of classes whose vtables have been used within
- /// this translation unit, and a bit that will be true if the vtable is
- /// required to be emitted (otherwise, it should be emitted only if needed
- /// by code generation).
- llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed;
-
- /// \brief A list of all of the dynamic classes in this translation
- /// unit.
- llvm::SmallVector<CXXRecordDecl *, 16> DynamicClasses;
-
- /// \brief Note that the vtable for the given class was used at the
- /// given location.
- void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
- bool DefinitionRequired = false);
-
- /// MarkVirtualMembersReferenced - Will mark all virtual members of the given
- /// CXXRecordDecl referenced.
- void MarkVirtualMembersReferenced(SourceLocation Loc,
- const CXXRecordDecl *RD);
-
- /// \brief Define all of the vtables that have been used in this
- /// translation unit and reference any virtual members used by those
- /// vtables.
- ///
- /// \returns true if any work was done, false otherwise.
- bool DefineUsedVTables();
-
- void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
-
- virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
- SourceLocation ColonLoc,
- MemInitTy **MemInits, unsigned NumMemInits,
- bool AnyErrors);
-
- void CheckCompletedCXXClass(CXXRecordDecl *Record);
- virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- DeclPtrTy TagDecl,
- SourceLocation LBrac,
- SourceLocation RBrac,
- AttributeList *AttrList);
-
- virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template);
- virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
- DeclPtrTy Record);
- virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
- DeclPtrTy Method);
- virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param);
- virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
- DeclPtrTy Method);
- virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
- DeclPtrTy Record);
-
- virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
- ExprArg AssertExpr,
- ExprArg AssertMessageExpr);
-
- FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc,
- TypeSourceInfo *TSInfo);
- DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
- MultiTemplateParamsArg TemplateParams);
- DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
- MultiTemplateParamsArg TemplateParams);
-
- QualType CheckConstructorDeclarator(Declarator &D, QualType R,
- FunctionDecl::StorageClass& SC);
- void CheckConstructor(CXXConstructorDecl *Constructor);
- QualType CheckDestructorDeclarator(Declarator &D, QualType R,
- FunctionDecl::StorageClass& SC);
- bool CheckDestructor(CXXDestructorDecl *Destructor);
- void CheckConversionDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC);
- DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
-
- //===--------------------------------------------------------------------===//
- // C++ Derived Classes
- //
-
- /// ActOnBaseSpecifier - Parsed a base specifier
- CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
- SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- QualType BaseType,
- SourceLocation BaseLoc);
-
- /// SetClassDeclAttributesFromBase - Copies class decl traits
- /// (such as whether the class has a trivial constructor,
- /// trivial destructor etc) from the given base class.
- void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
- const CXXRecordDecl *BaseClass,
- bool BaseIsVirtual);
-
- virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
- SourceRange SpecifierRange,
- bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation
- BaseLoc);
-
- bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
- unsigned NumBases);
- virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
- unsigned NumBases);
-
- bool IsDerivedFrom(QualType Derived, QualType Base);
- bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
-
- // FIXME: I don't like this name.
- void BuildBasePathArray(const CXXBasePaths &Paths,
- CXXBaseSpecifierArray &BasePath);
-
- bool BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath);
-
- bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
- SourceLocation Loc, SourceRange Range,
- CXXBaseSpecifierArray *BasePath = 0,
- bool IgnoreAccess = false);
- bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
- unsigned InaccessibleBaseID,
- unsigned AmbigiousBaseConvID,
- SourceLocation Loc, SourceRange Range,
- DeclarationName Name,
- CXXBaseSpecifierArray *BasePath);
-
- std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
-
- /// CheckOverridingFunctionReturnType - Checks whether the return types are
- /// covariant, according to C++ [class.virtual]p5.
- bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
- /// spec is a subset of base spec.
- bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- /// CheckOverridingFunctionAttributes - Checks whether attributes are
- /// incompatible or prevent overriding.
- bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
- const CXXMethodDecl *Old);
-
- bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
-
- //===--------------------------------------------------------------------===//
- // C++ Access Control
- //
-
- enum AccessResult {
- AR_accessible,
- AR_inaccessible,
- AR_dependent,
- AR_delayed
- };
-
- bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
- NamedDecl *PrevMemberDecl,
- AccessSpecifier LexicalAS);
-
- AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
- DeclAccessPair FoundDecl);
- AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
- DeclAccessPair FoundDecl);
- AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
- SourceRange PlacementRange,
- CXXRecordDecl *NamingClass,
- DeclAccessPair FoundDecl);
- AccessResult CheckConstructorAccess(SourceLocation Loc,
- CXXConstructorDecl *D,
- const InitializedEntity &Entity,
- AccessSpecifier Access,
- bool IsCopyBindingRefToTemp = false);
- AccessResult CheckDestructorAccess(SourceLocation Loc,
- CXXDestructorDecl *Dtor,
- const PartialDiagnostic &PDiag);
- AccessResult CheckDirectMemberAccess(SourceLocation Loc,
- NamedDecl *D,
- const PartialDiagnostic &PDiag);
- AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
- Expr *ObjectExpr,
- Expr *ArgExpr,
- DeclAccessPair FoundDecl);
- AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
- DeclAccessPair FoundDecl);
- AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
- QualType Base, QualType Derived,
- const CXXBasePath &Path,
- unsigned DiagID,
- bool ForceCheck = false,
- bool ForceUnprivileged = false);
- void CheckLookupAccess(const LookupResult &R);
-
- void HandleDependentAccessCheck(const DependentDiagnostic &DD,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- void PerformDependentDiagnostics(const DeclContext *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- void HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx);
-
- /// A flag to suppress access checking.
- bool SuppressAccessChecking;
-
- void ActOnStartSuppressingAccessChecks();
- void ActOnStopSuppressingAccessChecks();
-
- enum AbstractDiagSelID {
- AbstractNone = -1,
- AbstractReturnType,
- AbstractParamType,
- AbstractVariableType,
- AbstractFieldType
- };
-
- bool RequireNonAbstractType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD,
- const CXXRecordDecl *CurrentRD = 0);
-
- bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
- AbstractDiagSelID SelID = AbstractNone,
- const CXXRecordDecl *CurrentRD = 0);
-
- //===--------------------------------------------------------------------===//
- // C++ Overloaded Operators [C++ 13.5]
- //
-
- bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
-
- bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl);
-
- //===--------------------------------------------------------------------===//
- // C++ Templates [C++ 14]
- //
- void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
- QualType ObjectType, bool EnteringContext,
- bool &MemberOfUnknownSpecialization);
-
- virtual TemplateNameKind isTemplateName(Scope *S,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- TypeTy *ObjectType,
- bool EnteringContext,
- TemplateTy &Template,
- bool &MemberOfUnknownSpecialization);
-
- virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
- SourceLocation IILoc,
- Scope *S,
- const CXXScopeSpec *SS,
- TemplateTy &SuggestedTemplate,
- TemplateNameKind &SuggestedKind);
-
- bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
- TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
-
- virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
- SourceLocation EllipsisLoc,
- SourceLocation KeyLoc,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position,
- SourceLocation EqualLoc,
- TypeTy *DefaultArg);
-
- QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
- virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
- ExprArg DefaultArg);
- virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
- SourceLocation TmpLoc,
- TemplateParamsTy *Params,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
- const ParsedTemplateArgument &DefaultArg);
-
- virtual TemplateParamsTy *
- ActOnTemplateParameterList(unsigned Depth,
- SourceLocation ExportLoc,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- DeclPtrTy *Params, unsigned NumParams,
- SourceLocation RAngleLoc);
-
- /// \brief The context in which we are checking a template parameter
- /// list.
- enum TemplateParamListContext {
- TPC_ClassTemplate,
- TPC_FunctionTemplate,
- TPC_ClassTemplateMember,
- TPC_FriendFunctionTemplate
- };
-
- bool CheckTemplateParameterList(TemplateParameterList *NewParams,
- TemplateParameterList *OldParams,
- TemplateParamListContext TPC);
- TemplateParameterList *
- MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
- const CXXScopeSpec &SS,
- TemplateParameterList **ParamLists,
- unsigned NumParamLists,
- bool IsFriend,
- bool &IsExplicitSpecialization,
- bool &Invalid);
-
- DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- AttributeList *Attr,
- TemplateParameterList *TemplateParams,
- AccessSpecifier AS);
-
- void translateTemplateArguments(const ASTTemplateArgsPtr &In,
- TemplateArgumentListInfo &Out);
-
- QualType CheckTemplateIdType(TemplateName Template,
- SourceLocation TemplateLoc,
- const TemplateArgumentListInfo &TemplateArgs);
-
- virtual TypeResult
- ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc);
-
- virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
- TagUseKind TUK,
- DeclSpec::TST TagSpec,
- SourceLocation TagLoc);
-
- OwningExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- bool RequiresADL,
- const TemplateArgumentListInfo &TemplateArgs);
- OwningExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
- const TemplateArgumentListInfo &TemplateArgs);
-
- virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
- SourceLocation TemplateKWLoc,
- CXXScopeSpec &SS,
- UnqualifiedId &Name,
- TypeTy *ObjectType,
- bool EnteringContext,
- TemplateTy &Template);
-
- bool CheckClassTemplatePartialSpecializationArgs(
- TemplateParameterList *TemplateParams,
- const TemplateArgumentListBuilder &TemplateArgs,
- bool &MirrorsPrimaryTemplate);
-
- virtual DeclResult
- ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc,
- CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- AttributeList *Attr,
- MultiTemplateParamsArg TemplateParameterLists);
-
- virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
- MultiTemplateParamsArg TemplateParameterLists,
- Declarator &D);
-
- virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
- MultiTemplateParamsArg TemplateParameterLists,
- Declarator &D);
-
- bool
- CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
- TemplateSpecializationKind NewTSK,
- NamedDecl *PrevDecl,
- TemplateSpecializationKind PrevTSK,
- SourceLocation PrevPtOfInstantiation,
- bool &SuppressNew);
-
- bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
- const TemplateArgumentListInfo &ExplicitTemplateArgs,
- LookupResult &Previous);
-
- bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- LookupResult &Previous);
- bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
-
- virtual DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- const CXXScopeSpec &SS,
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation RAngleLoc,
- AttributeList *Attr);
-
- virtual DeclResult
- ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- unsigned TagSpec,
- SourceLocation KWLoc,
- CXXScopeSpec &SS,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- AttributeList *Attr);
-
- virtual DeclResult ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- Declarator &D);
-
- TemplateArgumentLoc
- SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- Decl *Param,
- TemplateArgumentListBuilder &Converted);
-
- /// \brief Specifies the context in which a particular template
- /// argument is being checked.
- enum CheckTemplateArgumentKind {
- /// \brief The template argument was specified in the code or was
- /// instantiated with some deduced template arguments.
- CTAK_Specified,
-
- /// \brief The template argument was deduced via template argument
- /// deduction.
- CTAK_Deduced,
-
- /// \brief The template argument was deduced from an array bound
- /// via template argument deduction.
- CTAK_DeducedFromArrayBound
- };
-
- bool CheckTemplateArgument(NamedDecl *Param,
- const TemplateArgumentLoc &Arg,
- TemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- TemplateArgumentListBuilder &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
-
- bool CheckTemplateArgumentList(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- const TemplateArgumentListInfo &TemplateArgs,
- bool PartialTemplateArgs,
- TemplateArgumentListBuilder &Converted);
-
- bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- const TemplateArgumentLoc &Arg,
- TemplateArgumentListBuilder &Converted);
-
- bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
- TypeSourceInfo *Arg);
- bool CheckTemplateArgumentPointerToMember(Expr *Arg,
- TemplateArgument &Converted);
- bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
- QualType InstantiatedParamType, Expr *&Arg,
- TemplateArgument &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
- bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- const TemplateArgumentLoc &Arg);
-
- OwningExprResult
- BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
- QualType ParamType,
- SourceLocation Loc);
- OwningExprResult
- BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
- SourceLocation Loc);
-
- /// \brief Enumeration describing how template parameter lists are compared
- /// for equality.
- enum TemplateParameterListEqualKind {
- /// \brief We are matching the template parameter lists of two templates
- /// that might be redeclarations.
- ///
- /// \code
- /// template<typename T> struct X;
- /// template<typename T> struct X;
- /// \endcode
- TPL_TemplateMatch,
-
- /// \brief We are matching the template parameter lists of two template
- /// template parameters as part of matching the template parameter lists
- /// of two templates that might be redeclarations.
- ///
- /// \code
- /// template<template<int I> class TT> struct X;
- /// template<template<int Value> class Other> struct X;
- /// \endcode
- TPL_TemplateTemplateParmMatch,
-
- /// \brief We are matching the template parameter lists of a template
- /// template argument against the template parameter lists of a template
- /// template parameter.
- ///
- /// \code
- /// template<template<int Value> class Metafun> struct X;
- /// template<int Value> struct integer_c;
- /// X<integer_c> xic;
- /// \endcode
- TPL_TemplateTemplateArgumentMatch
- };
-
- bool TemplateParameterListsAreEqual(TemplateParameterList *New,
- TemplateParameterList *Old,
- bool Complain,
- TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc
- = SourceLocation());
-
- bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
-
- /// \brief Called when the parser has parsed a C++ typename
- /// specifier, e.g., "typename T::type".
- ///
- /// \param S The scope in which this typename type occurs.
- /// \param TypenameLoc the location of the 'typename' keyword
- /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
- /// \param II the identifier we're retrieving (e.g., 'type' in the example).
- /// \param IdLoc the location of the identifier.
- virtual TypeResult
- ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, const IdentifierInfo &II,
- SourceLocation IdLoc);
-
- /// \brief Called when the parser has parsed a C++ typename
- /// specifier that ends in a template-id, e.g.,
- /// "typename MetaFun::template apply<T1, T2>".
- ///
- /// \param S The scope in which this typename type occurs.
- /// \param TypenameLoc the location of the 'typename' keyword
- /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
- /// \param TemplateLoc the location of the 'template' keyword, if any.
- /// \param Ty the type that the typename specifier refers to.
- virtual TypeResult
- ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, SourceLocation TemplateLoc,
- TypeTy *Ty);
-
- QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo &II,
- SourceLocation KeywordLoc,
- SourceRange NNSRange,
- SourceLocation IILoc);
-
- TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
- SourceLocation Loc,
- DeclarationName Name);
- bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
-
- std::string
- getTemplateArgumentBindingsText(const TemplateParameterList *Params,
- const TemplateArgumentList &Args);
-
- std::string
- getTemplateArgumentBindingsText(const TemplateParameterList *Params,
- const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Describes the result of template argument deduction.
- ///
- /// The TemplateDeductionResult enumeration describes the result of
- /// template argument deduction, as returned from
- /// DeduceTemplateArguments(). The separate TemplateDeductionInfo
- /// structure provides additional information about the results of
- /// template argument deduction, e.g., the deduced template argument
- /// list (if successful) or the specific template parameters or
- /// deduced arguments that were involved in the failure.
- enum TemplateDeductionResult {
- /// \brief Template argument deduction was successful.
- TDK_Success = 0,
- /// \brief Template argument deduction exceeded the maximum template
- /// instantiation depth (which has already been diagnosed).
- TDK_InstantiationDepth,
- /// \brief Template argument deduction did not deduce a value
- /// for every template parameter.
- TDK_Incomplete,
- /// \brief Template argument deduction produced inconsistent
- /// deduced values for the given template parameter.
- TDK_Inconsistent,
- /// \brief Template argument deduction failed due to inconsistent
- /// cv-qualifiers on a template parameter type that would
- /// otherwise be deduced, e.g., we tried to deduce T in "const T"
- /// but were given a non-const "X".
- TDK_InconsistentQuals,
- /// \brief Substitution of the deduced template argument values
- /// resulted in an error.
- TDK_SubstitutionFailure,
- /// \brief Substitution of the deduced template argument values
- /// into a non-deduced context produced a type or value that
- /// produces a type that does not match the original template
- /// arguments provided.
- TDK_NonDeducedMismatch,
- /// \brief When performing template argument deduction for a function
- /// template, there were too many call arguments.
- TDK_TooManyArguments,
- /// \brief When performing template argument deduction for a function
- /// template, there were too few call arguments.
- TDK_TooFewArguments,
- /// \brief The explicitly-specified template arguments were not valid
- /// template arguments for the given template.
- TDK_InvalidExplicitArguments,
- /// \brief The arguments included an overloaded function name that could
- /// not be resolved to a suitable function.
- TDK_FailedOverloadResolution
- };
-
- /// \brief Provides information about an attempted template argument
- /// deduction, whose success or failure was described by a
- /// TemplateDeductionResult value.
- class TemplateDeductionInfo {
- /// \brief The context in which the template arguments are stored.
- ASTContext &Context;
-
- /// \brief The deduced template argument list.
- ///
- TemplateArgumentList *Deduced;
-
- /// \brief The source location at which template argument
- /// deduction is occurring.
- SourceLocation Loc;
-
- // do not implement these
- TemplateDeductionInfo(const TemplateDeductionInfo&);
- TemplateDeductionInfo &operator=(const TemplateDeductionInfo&);
-
- public:
- TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc)
- : Context(Context), Deduced(0), Loc(Loc) { }
-
- ~TemplateDeductionInfo() {
- // FIXME: if (Deduced) Deduced->Destroy(Context);
- }
-
- /// \brief Returns the location at which template argument is
- /// occuring.
- SourceLocation getLocation() const {
- return Loc;
- }
-
- /// \brief Take ownership of the deduced template argument list.
- TemplateArgumentList *take() {
- TemplateArgumentList *Result = Deduced;
- Deduced = 0;
- return Result;
- }
-
- /// \brief Provide a new template argument list that contains the
- /// results of template argument deduction.
- void reset(TemplateArgumentList *NewDeduced) {
- // FIXME: if (Deduced) Deduced->Destroy(Context);
- Deduced = NewDeduced;
- }
-
- /// \brief The template parameter to which a template argument
- /// deduction failure refers.
- ///
- /// Depending on the result of template argument deduction, this
- /// template parameter may have different meanings:
- ///
- /// TDK_Incomplete: this is the first template parameter whose
- /// corresponding template argument was not deduced.
- ///
- /// TDK_Inconsistent: this is the template parameter for which
- /// two different template argument values were deduced.
- TemplateParameter Param;
-
- /// \brief The first template argument to which the template
- /// argument deduction failure refers.
- ///
- /// Depending on the result of the template argument deduction,
- /// this template argument may have different meanings:
- ///
- /// TDK_Inconsistent: this argument is the first value deduced
- /// for the corresponding template parameter.
- ///
- /// TDK_SubstitutionFailure: this argument is the template
- /// argument we were instantiating when we encountered an error.
- ///
- /// TDK_NonDeducedMismatch: this is the template argument
- /// provided in the source code.
- TemplateArgument FirstArg;
-
- /// \brief The second template argument to which the template
- /// argument deduction failure refers.
- ///
- /// FIXME: Finish documenting this.
- TemplateArgument SecondArg;
- };
-
- TemplateDeductionResult
- DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
- const TemplateArgumentList &TemplateArgs,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgumentListInfo &ExplicitTemplateArgs,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- llvm::SmallVectorImpl<QualType> &ParamTypes,
- QualType *FunctionType,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned NumExplicitlySpecified,
- FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- Expr **Args, unsigned NumArgs,
- FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- QualType ArgFunctionType,
- FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- QualType ToType,
- CXXConversionDecl *&Specialization,
- TemplateDeductionInfo &Info);
-
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgumentListInfo *ExplicitTemplateArgs,
- FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info);
-
- FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
- FunctionTemplateDecl *FT2,
- SourceLocation Loc,
- TemplatePartialOrderingContext TPOC);
- UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
- UnresolvedSetIterator SEnd,
- TemplatePartialOrderingContext TPOC,
- SourceLocation Loc,
- const PartialDiagnostic &NoneDiag,
- const PartialDiagnostic &AmbigDiag,
- const PartialDiagnostic &CandidateDiag);
-
- ClassTemplatePartialSpecializationDecl *
- getMoreSpecializedPartialSpecialization(
- ClassTemplatePartialSpecializationDecl *PS1,
- ClassTemplatePartialSpecializationDecl *PS2,
- SourceLocation Loc);
-
- void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallVectorImpl<bool> &Used);
- void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
- llvm::SmallVectorImpl<bool> &Deduced);
-
- //===--------------------------------------------------------------------===//
- // C++ Template Instantiation
- //
-
- MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
- const TemplateArgumentList *Innermost = 0,
- bool RelativeToPrimary = false,
- const FunctionDecl *Pattern = 0);
-
- /// \brief A template instantiation that is currently in progress.
- struct ActiveTemplateInstantiation {
- /// \brief The kind of template instantiation we are performing
- enum InstantiationKind {
- /// We are instantiating a template declaration. The entity is
- /// the declaration we're instantiating (e.g., a CXXRecordDecl).
- TemplateInstantiation,
-
- /// We are instantiating a default argument for a template
- /// parameter. The Entity is the template, and
- /// TemplateArgs/NumTemplateArguments provides the template
- /// arguments as specified.
- /// FIXME: Use a TemplateArgumentList
- DefaultTemplateArgumentInstantiation,
-
- /// We are instantiating a default argument for a function.
- /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
- /// provides the template arguments as specified.
- DefaultFunctionArgumentInstantiation,
-
- /// We are substituting explicit template arguments provided for
- /// a function template. The entity is a FunctionTemplateDecl.
- ExplicitTemplateArgumentSubstitution,
-
- /// We are substituting template argument determined as part of
- /// template argument deduction for either a class template
- /// partial specialization or a function template. The
- /// Entity is either a ClassTemplatePartialSpecializationDecl or
- /// a FunctionTemplateDecl.
- DeducedTemplateArgumentSubstitution,
-
- /// We are substituting prior template arguments into a new
- /// template parameter. The template parameter itself is either a
- /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
- PriorTemplateArgumentSubstitution,
-
- /// We are checking the validity of a default template argument that
- /// has been used when naming a template-id.
- DefaultTemplateArgumentChecking
- } Kind;
-
- /// \brief The point of instantiation within the source code.
- SourceLocation PointOfInstantiation;
-
- /// \brief The template in which we are performing the instantiation,
- /// for substitutions of prior template arguments.
- TemplateDecl *Template;
-
- /// \brief The entity that is being instantiated.
- uintptr_t Entity;
-
- /// \brief The list of template arguments we are substituting, if they
- /// are not part of the entity.
- const TemplateArgument *TemplateArgs;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- /// \brief The source range that covers the construct that cause
- /// the instantiation, e.g., the template-id that causes a class
- /// template instantiation.
- SourceRange InstantiationRange;
-
- ActiveTemplateInstantiation()
- : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0),
- NumTemplateArgs(0) {}
-
- /// \brief Determines whether this template is an actual instantiation
- /// that should be counted toward the maximum instantiation depth.
- bool isInstantiationRecord() const;
-
- friend bool operator==(const ActiveTemplateInstantiation &X,
- const ActiveTemplateInstantiation &Y) {
- if (X.Kind != Y.Kind)
- return false;
-
- if (X.Entity != Y.Entity)
- return false;
-
- switch (X.Kind) {
- case TemplateInstantiation:
- return true;
-
- case PriorTemplateArgumentSubstitution:
- case DefaultTemplateArgumentChecking:
- if (X.Template != Y.Template)
- return false;
-
- // Fall through
-
- case DefaultTemplateArgumentInstantiation:
- case ExplicitTemplateArgumentSubstitution:
- case DeducedTemplateArgumentSubstitution:
- case DefaultFunctionArgumentInstantiation:
- return X.TemplateArgs == Y.TemplateArgs;
-
- }
-
- return true;
- }
-
- friend bool operator!=(const ActiveTemplateInstantiation &X,
- const ActiveTemplateInstantiation &Y) {
- return !(X == Y);
- }
- };
-
- /// \brief List of active template instantiations.
- ///
- /// This vector is treated as a stack. As one template instantiation
- /// requires another template instantiation, additional
- /// instantiations are pushed onto the stack up to a
- /// user-configurable limit LangOptions::InstantiationDepth.
- llvm::SmallVector<ActiveTemplateInstantiation, 16>
- ActiveTemplateInstantiations;
-
- /// \brief The number of ActiveTemplateInstantiation entries in
- /// \c ActiveTemplateInstantiations that are not actual instantiations and,
- /// therefore, should not be counted as part of the instantiation depth.
- unsigned NonInstantiationEntries;
-
- /// \brief The last template from which a template instantiation
- /// error or warning was produced.
- ///
- /// This value is used to suppress printing of redundant template
- /// instantiation backtraces when there are multiple errors in the
- /// same instantiation. FIXME: Does this belong in Sema? It's tough
- /// to implement it anywhere else.
- ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
-
- /// \brief The stack of calls expression undergoing template instantiation.
- ///
- /// The top of this stack is used by a fixit instantiating unresolved
- /// function calls to fix the AST to match the textual change it prints.
- llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation;
-
- /// \brief A stack object to be created when performing template
- /// instantiation.
- ///
- /// Construction of an object of type \c InstantiatingTemplate
- /// pushes the current instantiation onto the stack of active
- /// instantiations. If the size of this stack exceeds the maximum
- /// number of recursive template instantiations, construction
- /// produces an error and evaluates true.
- ///
- /// Destruction of this object will pop the named instantiation off
- /// the stack.
- struct InstantiatingTemplate {
- /// \brief Note that we are instantiating a class template,
- /// function template, or a member thereof.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- Decl *Entity,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating a default argument in a
- /// template-id.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating a default argument in a
- /// template-id.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- ActiveTemplateInstantiation::InstantiationKind Kind,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are instantiating as part of template
- /// argument deduction for a class template partial
- /// specialization.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- ClassTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange = SourceRange());
-
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- ParmVarDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange = SourceRange());
-
- /// \brief Note that we are substituting prior template arguments into a
- /// non-type or template template parameter.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- NonTypeTemplateParmDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange);
-
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- TemplateTemplateParmDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange);
-
- /// \brief Note that we are checking the default template argument
- /// against the template parameter for a given template-id.
- InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- TemplateDecl *Template,
- NamedDecl *Param,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceRange InstantiationRange);
-
-
- /// \brief Note that we have finished instantiating this template.
- void Clear();
-
- ~InstantiatingTemplate() { Clear(); }
-
- /// \brief Determines whether we have exceeded the maximum
- /// recursive template instantiations.
- operator bool() const { return Invalid; }
-
- private:
- Sema &SemaRef;
- bool Invalid;
-
- bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
- SourceRange InstantiationRange);
-
- InstantiatingTemplate(const InstantiatingTemplate&); // not implemented
-
- InstantiatingTemplate&
- operator=(const InstantiatingTemplate&); // not implemented
- };
-
- void PrintInstantiationStack();
-
- /// \brief Determines whether we are currently in a context where
- /// template argument substitution failures are not considered
- /// errors.
- ///
- /// When this routine returns true, the emission of most diagnostics
- /// will be suppressed and there will be no local error recovery.
- bool isSFINAEContext() const;
-
- /// \brief RAII class used to determine whether SFINAE has
- /// trapped any errors that occur during template argument
- /// deduction.
- class SFINAETrap {
- Sema &SemaRef;
- unsigned PrevSFINAEErrors;
- public:
- explicit SFINAETrap(Sema &SemaRef)
- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors) { }
-
- ~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; }
-
- /// \brief Determine whether any SFINAE errors have been trapped.
- bool hasErrorOccurred() const {
- return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
- }
- };
-
- /// \brief RAII class that determines when any errors have occurred
- /// between the time the instance was created and the time it was
- /// queried.
- class ErrorTrap {
- Sema &SemaRef;
- unsigned PrevErrors;
-
- public:
- explicit ErrorTrap(Sema &SemaRef)
- : SemaRef(SemaRef), PrevErrors(SemaRef.getDiagnostics().getNumErrors()) {}
-
- /// \brief Determine whether any errors have occurred since this
- /// object instance was created.
- bool hasErrorOccurred() const {
- return SemaRef.getDiagnostics().getNumErrors() > PrevErrors;
- }
- };
-
- /// \brief A stack-allocated class that identifies which local
- /// variable declaration instantiations are present in this scope.
- ///
- /// A new instance of this class type will be created whenever we
- /// instantiate a new function declaration, which will have its own
- /// set of parameter declarations.
- class LocalInstantiationScope {
- /// \brief Reference to the semantic analysis that is performing
- /// this template instantiation.
- Sema &SemaRef;
-
- /// \brief A mapping from local declarations that occur
- /// within a template to their instantiations.
- ///
- /// This mapping is used during instantiation to keep track of,
- /// e.g., function parameter and variable declarations. For example,
- /// given:
- ///
- /// \code
- /// template<typename T> T add(T x, T y) { return x + y; }
- /// \endcode
- ///
- /// when we instantiate add<int>, we will introduce a mapping from
- /// the ParmVarDecl for 'x' that occurs in the template to the
- /// instantiated ParmVarDecl for 'x'.
- llvm::DenseMap<const Decl *, Decl *> LocalDecls;
-
- /// \brief The outer scope, which contains local variable
- /// definitions from some other instantiation (that may not be
- /// relevant to this particular scope).
- LocalInstantiationScope *Outer;
-
- /// \brief Whether we have already exited this scope.
- bool Exited;
-
- /// \brief Whether to combine this scope with the outer scope, such that
- /// lookup will search our outer scope.
- bool CombineWithOuterScope;
-
- // This class is non-copyable
- LocalInstantiationScope(const LocalInstantiationScope &);
- LocalInstantiationScope &operator=(const LocalInstantiationScope &);
-
- public:
- LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
- : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
- Exited(false), CombineWithOuterScope(CombineWithOuterScope)
- {
- SemaRef.CurrentInstantiationScope = this;
- }
-
- ~LocalInstantiationScope() {
- Exit();
- }
-
- /// \brief Exit this local instantiation scope early.
- void Exit() {
- if (Exited)
- return;
-
- SemaRef.CurrentInstantiationScope = Outer;
- Exited = true;
- }
-
- Decl *getInstantiationOf(const Decl *D);
-
- VarDecl *getInstantiationOf(const VarDecl *Var) {
- return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var)));
- }
-
- ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) {
- return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var)));
- }
-
- NonTypeTemplateParmDecl *getInstantiationOf(
- const NonTypeTemplateParmDecl *Var) {
- return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var)));
- }
-
- void InstantiatedLocal(const Decl *D, Decl *Inst);
- };
-
- /// \brief The current instantiation scope used to store local
- /// variables.
- LocalInstantiationScope *CurrentInstantiationScope;
-
- /// \brief The number of typos corrected by CorrectTypo.
- unsigned TyposCorrected;
-
- /// \brief Worker object for performing CFG-based warnings.
- sema::AnalysisBasedWarnings AnalysisWarnings;
-
- /// \brief An entity for which implicit template instantiation is required.
- ///
- /// The source location associated with the declaration is the first place in
- /// the source code where the declaration was "used". It is not necessarily
- /// the point of instantiation (which will be either before or after the
- /// namespace-scope declaration that triggered this implicit instantiation),
- /// However, it is the location that diagnostics should generally refer to,
- /// because users will need to know what code triggered the instantiation.
- typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
-
- /// \brief The queue of implicit template instantiations that are required
- /// but have not yet been performed.
- std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
-
- /// \brief The queue of implicit template instantiations that are required
- /// and must be performed within the current local scope.
- ///
- /// This queue is only used for member functions of local classes in
- /// templates, which must be instantiated in the same scope as their
- /// enclosing function, so that they can reference function-local
- /// types, static variables, enumerators, etc.
- std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
-
- void PerformPendingImplicitInstantiations(bool LocalOnly = false);
-
- TypeSourceInfo *SubstType(TypeSourceInfo *T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- QualType SubstType(QualType T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity);
-
- TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc,
- DeclarationName Entity);
- ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- OwningExprResult SubstExpr(Expr *E,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- OwningStmtResult SubstStmt(Stmt *S,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- Decl *SubstDecl(Decl *D, DeclContext *Owner,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- bool
- SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
- CXXRecordDecl *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- bool
- InstantiateClass(SourceLocation PointOfInstantiation,
- CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TemplateSpecializationKind TSK,
- bool Complain = true);
-
- bool
- InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK,
- bool Complain = true);
-
- void InstantiateClassMembers(SourceLocation PointOfInstantiation,
- CXXRecordDecl *Instantiation,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- TemplateSpecializationKind TSK);
-
- void InstantiateClassTemplateSpecializationMembers(
- SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK);
-
- NestedNameSpecifier *
- SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
- SourceRange Range,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- TemplateName
- SubstTemplateName(TemplateName Name, SourceLocation Loc,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function,
- bool Recursive = false,
- bool DefinitionRequired = false);
- void InstantiateStaticDataMemberDefinition(
- SourceLocation PointOfInstantiation,
- VarDecl *Var,
- bool Recursive = false,
- bool DefinitionRequired = false);
-
- void InstantiateMemInitializers(CXXConstructorDecl *New,
- const CXXConstructorDecl *Tmpl,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
- const MultiLevelTemplateArgumentList &TemplateArgs);
- DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
- const MultiLevelTemplateArgumentList &TemplateArgs);
-
- // Objective-C declarations.
- virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperName,
- SourceLocation SuperLoc,
- const DeclPtrTy *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- virtual DeclPtrTy ActOnCompatiblityAlias(
- SourceLocation AtCompatibilityAliasLoc,
- IdentifierInfo *AliasName, SourceLocation AliasLocation,
- IdentifierInfo *ClassName, SourceLocation ClassLocation);
-
- void CheckForwardProtocolDeclarationForCircularDependency(
- IdentifierInfo *PName,
- SourceLocation &PLoc, SourceLocation PrevLoc,
- const ObjCList<ObjCProtocolDecl> &PList);
-
- virtual DeclPtrTy ActOnStartProtocolInterface(
- SourceLocation AtProtoInterfaceLoc,
- IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
- const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc,
- AttributeList *AttrList);
-
- virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CategoryName,
- SourceLocation CategoryLoc,
- const DeclPtrTy *ProtoRefs,
- unsigned NumProtoRefs,
- const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc);
-
- virtual DeclPtrTy ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc);
-
- virtual DeclPtrTy ActOnStartCategoryImplementation(
- SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CatName,
- SourceLocation CatLoc);
-
- virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
- IdentifierInfo **IdentList,
- SourceLocation *IdentLocs,
- unsigned NumElts);
-
- virtual DeclPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
- const IdentifierLocPair *IdentList,
- unsigned NumElts,
- AttributeList *attrList);
-
- virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
- const IdentifierLocPair *ProtocolId,
- unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclPtrTy> &Protocols);
-
- /// Ensure attributes are consistent with type.
- /// \param [in, out] Attributes The attributes to check; they will
- /// be modified to be consistent with \arg PropertyTy.
- void CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
- SourceLocation Loc,
- unsigned &Attributes);
- void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
- void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
- ObjCPropertyDecl *SuperProperty,
- const IdentifierInfo *Name);
- void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
-
- void CompareMethodParamsInBaseAndSuper(Decl *IDecl,
- ObjCMethodDecl *MethodDecl,
- bool IsInstance);
-
- void CompareProperties(Decl *CDecl, DeclPtrTy MergeProtocols);
-
- void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
- ObjCInterfaceDecl *ID);
-
- void MatchOneProtocolPropertiesInClass(Decl *CDecl,
- ObjCProtocolDecl *PDecl);
-
- virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
- DeclPtrTy classDecl,
- DeclPtrTy *allMethods = 0, unsigned allNum = 0,
- DeclPtrTy *allProperties = 0, unsigned pNum = 0,
- DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
-
- virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD, ObjCDeclSpec &ODS,
- Selector GetterSel, Selector SetterSel,
- DeclPtrTy ClassCategory,
- bool *OverridingProperty,
- tok::ObjCKeywordKind MethodImplKind);
-
- virtual DeclPtrTy ActOnPropertyImplDecl(Scope *S,
- SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool ImplKind,DeclPtrTy ClassImplDecl,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar);
-
- virtual DeclPtrTy ActOnMethodDeclaration(
- SourceLocation BeginLoc, // location of the + or -.
- SourceLocation EndLoc, // location of the ; or {.
- tok::TokenKind MethodType,
- DeclPtrTy ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
- Selector Sel,
- // optional arguments. The number of types/arguments is obtained
- // from the Sel.getNumArgs().
- ObjCArgInfo *ArgInfo,
- DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
- AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
- bool isVariadic = false);
-
- // Helper method for ActOnClassMethod/ActOnInstanceMethod.
- // Will search "local" class/category implementations for a method decl.
- // Will also search in class's root looking for instance method.
- // Returns 0 if no method is found.
- ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
- ObjCInterfaceDecl *CDecl);
- ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
- ObjCInterfaceDecl *ClassDecl);
-
- OwningExprResult
- HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
- Expr *BaseExpr,
- DeclarationName MemberName,
- SourceLocation MemberLoc);
-
- virtual OwningExprResult
- ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
- IdentifierInfo &propertyName,
- SourceLocation receiverNameLoc,
- SourceLocation propertyNameLoc);
-
- virtual ObjCMessageKind getObjCMessageKind(Scope *S,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- bool IsSuper,
- bool HasTrailingDot,
- TypeTy *&ReceiverType);
-
- virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
- Selector Sel,
- SourceLocation LBracLoc,
- SourceLocation SelectorLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- OwningExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
- QualType ReceiverType,
- SourceLocation SuperLoc,
- Selector Sel,
- ObjCMethodDecl *Method,
- SourceLocation LBracLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- virtual OwningExprResult ActOnClassMessage(Scope *S,
- TypeTy *Receiver,
- Selector Sel,
- SourceLocation LBracLoc,
- SourceLocation SelectorLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- OwningExprResult BuildInstanceMessage(ExprArg Receiver,
- QualType ReceiverType,
- SourceLocation SuperLoc,
- Selector Sel,
- ObjCMethodDecl *Method,
- SourceLocation LBracLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
- virtual OwningExprResult ActOnInstanceMessage(Scope *S,
- ExprArg Receiver,
- Selector Sel,
- SourceLocation LBracLoc,
- SourceLocation SelectorLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args);
-
-
- /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
- virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
- SourceLocation PragmaLoc,
- SourceLocation KindLoc);
-
- /// ActOnPragmaPack - Called on well formed #pragma pack(...).
- virtual void ActOnPragmaPack(PragmaPackKind Kind,
- IdentifierInfo *Name,
- ExprTy *Alignment,
- SourceLocation PragmaLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- /// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
- virtual void ActOnPragmaUnused(const Token *Identifiers,
- unsigned NumIdentifiers, Scope *curScope,
- SourceLocation PragmaLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
-
- NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
- void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
-
- /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
- virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
- SourceLocation PragmaLoc,
- SourceLocation WeakNameLoc);
-
- /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
- virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
- IdentifierInfo* AliasName,
- SourceLocation PragmaLoc,
- SourceLocation WeakNameLoc,
- SourceLocation AliasNameLoc);
-
- /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
- /// a the record decl, to handle '#pragma pack' and '#pragma options align'.
- void AddAlignmentAttributesForRecord(RecordDecl *RD);
-
- /// FreePackedContext - Deallocate and null out PackContext.
- void FreePackedContext();
-
- /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
- void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
-
- /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
- /// cast. If there is already an implicit cast, merge into the existing one.
- /// If isLvalue, the result of the cast is an lvalue.
- void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind,
- bool isLvalue = false,
- CXXBaseSpecifierArray BasePath =
- CXXBaseSpecifierArray());
-
- // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
- // functions and arrays to their respective pointers (C99 6.3.2.1).
- Expr *UsualUnaryConversions(Expr *&expr);
-
- // DefaultFunctionArrayConversion - converts functions and arrays
- // to their respective pointers (C99 6.3.2.1).
- void DefaultFunctionArrayConversion(Expr *&expr);
-
- // DefaultFunctionArrayLvalueConversion - converts functions and
- // arrays to their respective pointers and performs the
- // lvalue-to-rvalue conversion.
- void DefaultFunctionArrayLvalueConversion(Expr *&expr);
-
- // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
- // do not have a prototype. Integer promotions are performed on each
- // argument, and arguments that have type float are promoted to double.
- void DefaultArgumentPromotion(Expr *&Expr);
-
- // Used for emitting the right warning by DefaultVariadicArgumentPromotion
- enum VariadicCallType {
- VariadicFunction,
- VariadicBlock,
- VariadicMethod,
- VariadicConstructor,
- VariadicDoesNotApply
- };
-
- /// GatherArgumentsForCall - Collector argument expressions for various
- /// form of call prototypes.
- bool GatherArgumentsForCall(SourceLocation CallLoc,
- FunctionDecl *FDecl,
- const FunctionProtoType *Proto,
- unsigned FirstProtoArg,
- Expr **Args, unsigned NumArgs,
- llvm::SmallVector<Expr *, 8> &AllArgs,
- VariadicCallType CallType = VariadicDoesNotApply);
-
- // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
- // will warn if the resulting type is not a POD type.
- bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
- FunctionDecl *FDecl);
-
- // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
- // operands and then handles various conversions that are common to binary
- // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
- // routine returns the first non-arithmetic type found. The client is
- // responsible for emitting appropriate error diagnostics.
- QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
- bool isCompAssign = false);
-
- /// AssignConvertType - All of the 'assignment' semantic checks return this
- /// enum to indicate whether the assignment was allowed. These checks are
- /// done for simple assignments, as well as initialization, return from
- /// function, argument passing, etc. The query is phrased in terms of a
- /// source and destination type.
- enum AssignConvertType {
- /// Compatible - the types are compatible according to the standard.
- Compatible,
-
- /// PointerToInt - The assignment converts a pointer to an int, which we
- /// accept as an extension.
- PointerToInt,
-
- /// IntToPointer - The assignment converts an int to a pointer, which we
- /// accept as an extension.
- IntToPointer,
-
- /// FunctionVoidPointer - The assignment is between a function pointer and
- /// void*, which the standard doesn't allow, but we accept as an extension.
- FunctionVoidPointer,
-
- /// IncompatiblePointer - The assignment is between two pointers types that
- /// are not compatible, but we accept them as an extension.
- IncompatiblePointer,
-
- /// IncompatiblePointer - The assignment is between two pointers types which
- /// point to integers which have a different sign, but are otherwise identical.
- /// This is a subset of the above, but broken out because it's by far the most
- /// common case of incompatible pointers.
- IncompatiblePointerSign,
-
- /// CompatiblePointerDiscardsQualifiers - The assignment discards
- /// c/v/r qualifiers, which we accept as an extension.
- CompatiblePointerDiscardsQualifiers,
-
- /// IncompatibleNestedPointerQualifiers - The assignment is between two
- /// nested pointer types, and the qualifiers other than the first two
- /// levels differ e.g. char ** -> const char **, but we accept them as an
- /// extension.
- IncompatibleNestedPointerQualifiers,
-
- /// IncompatibleVectors - The assignment is between two vector types that
- /// have the same size, which we accept as an extension.
- IncompatibleVectors,
-
- /// IntToBlockPointer - The assignment converts an int to a block
- /// pointer. We disallow this.
- IntToBlockPointer,
-
- /// IncompatibleBlockPointer - The assignment is between two block
- /// pointers types that are not compatible.
- IncompatibleBlockPointer,
-
- /// IncompatibleObjCQualifiedId - The assignment is between a qualified
- /// id type and something else (that is incompatible with it). For example,
- /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
- IncompatibleObjCQualifiedId,
-
- /// Incompatible - We reject this conversion outright, it is invalid to
- /// represent it in the AST.
- Incompatible
- };
-
- /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
- /// assignment conversion type specified by ConvTy. This returns true if the
- /// conversion was invalid or false if the conversion was accepted.
- bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
- SourceLocation Loc,
- QualType DstType, QualType SrcType,
- Expr *SrcExpr, AssignmentAction Action,
- bool *Complained = 0);
-
- /// CheckAssignmentConstraints - Perform type checking for assignment,
- /// argument passing, variable initialization, and function return values.
- /// This routine is only used by the following two methods. C99 6.5.16.
- AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
-
- // CheckSingleAssignmentConstraints - Currently used by
- // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
- // this routine performs the default function/array converions.
- AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
- Expr *&rExpr);
-
- // \brief If the lhs type is a transparent union, check whether we
- // can initialize the transparent union with the given expression.
- AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
- Expr *&rExpr);
-
- // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
- AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
- QualType rhsType);
-
- AssignConvertType CheckObjCPointerTypesForAssignment(QualType lhsType,
- QualType rhsType);
-
- // Helper function for CheckAssignmentConstraints involving two
- // block pointer types.
- AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
- QualType rhsType);
-
- bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
-
- bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
-
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit = false);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- AssignmentAction Action,
- bool AllowExplicit,
- ImplicitConversionSequence& ICS);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- const ImplicitConversionSequence& ICS,
- AssignmentAction Action,
- bool IgnoreBaseAccess = false);
- bool PerformImplicitConversion(Expr *&From, QualType ToType,
- const StandardConversionSequence& SCS,
- AssignmentAction Action,bool IgnoreBaseAccess);
-
- /// the following "Check" methods will return a valid/converted QualType
- /// or a null QualType (indicating an error diagnostic was issued).
-
- /// type checking binary operators (subroutines of CreateBuiltinBinOp).
- QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- QualType CheckPointerToMemberOperands( // C++ 5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect);
- QualType CheckMultiplyDivideOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
- bool isDivide);
- QualType CheckRemainderOperands( // C99 6.5.5
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- QualType CheckAdditionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
- QualType CheckSubtractionOperands( // C99 6.5.6
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
- QualType CheckShiftOperands( // C99 6.5.7
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- QualType CheckCompareOperands( // C99 6.5.8/9
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
- bool isRelational);
- QualType CheckBitwiseOperands( // C99 6.5.[10...12]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
- QualType CheckLogicalOperands( // C99 6.5.[13,14]
- Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc);
- // CheckAssignmentOperands is used for both simple and compound assignment.
- // For simple assignment, pass both expressions and a null converted type.
- // For compound assignment, pass both expressions and the converted type.
- QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
- Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
- QualType CheckCommaOperands( // C99 6.5.17
- Expr *lex, Expr *&rex, SourceLocation OpLoc);
- QualType CheckConditionalOperands( // C99 6.5.15
- Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
- QualType CXXCheckConditionalOperands( // C++ 5.16
- Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
- QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
- bool *NonStandardCompositeType = 0);
-
- QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
- SourceLocation questionLoc);
-
- /// type checking for vector binary operators.
- QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
- QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
- SourceLocation l, bool isRel);
-
- /// type checking unary operators (subroutines of ActOnUnaryOp).
- /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
- QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
- bool isInc, bool isPrefix);
- QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
- QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
- QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal);
-
- /// type checking primary expressions.
- QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
- const IdentifierInfo *Comp,
- SourceLocation CmpLoc);
-
- /// type checking declaration initializers (C99 6.7.8)
- bool CheckInitList(const InitializedEntity &Entity,
- InitListExpr *&InitList, QualType &DeclType);
- bool CheckForConstantInitializer(Expr *e, QualType t);
-
- // type checking C++ declaration initializers (C++ [dcl.init]).
-
- /// ReferenceCompareResult - Expresses the result of comparing two
- /// types (cv1 T1 and cv2 T2) to determine their compatibility for the
- /// purposes of initialization by reference (C++ [dcl.init.ref]p4).
- enum ReferenceCompareResult {
- /// Ref_Incompatible - The two types are incompatible, so direct
- /// reference binding is not possible.
- Ref_Incompatible = 0,
- /// Ref_Related - The two types are reference-related, which means
- /// that their unqualified forms (T1 and T2) are either the same
- /// or T1 is a base class of T2.
- Ref_Related,
- /// Ref_Compatible_With_Added_Qualification - The two types are
- /// reference-compatible with added qualification, meaning that
- /// they are reference-compatible and the qualifiers on T1 (cv1)
- /// are greater than the qualifiers on T2 (cv2).
- Ref_Compatible_With_Added_Qualification,
- /// Ref_Compatible - The two types are reference-compatible and
- /// have equivalent qualifiers (cv1 == cv2).
- Ref_Compatible
- };
-
- ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc,
- QualType T1, QualType T2,
- bool& DerivedToBase);
-
- /// CheckCastTypes - Check type constraints for casting between types under
- /// C semantics, or forward to CXXCheckCStyleCast in C++.
- bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath,
- bool FunctionalStyle = false);
-
- // CheckVectorCast - check type constraints for vectors.
- // Since vectors are an extension, there are no C standard reference for this.
- // We allow casting between vectors and integer datatypes of the same size.
- // returns true if the cast is invalid
- bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
- CastExpr::CastKind &Kind);
-
- // CheckExtVectorCast - check type constraints for extended vectors.
- // Since vectors are an extension, there are no C standard reference for this.
- // We allow casting between vectors and integer datatypes of the same size,
- // or vectors and the element type of that vector.
- // returns true if the cast is invalid
- bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind);
-
- /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
- /// cast under C++ semantics.
- bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath,
- bool FunctionalStyle);
-
- /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
- /// \param Method - May be null.
- /// \param [out] ReturnType - The return type of the send.
- /// \return true iff there were any incompatible types.
- bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
- ObjCMethodDecl *Method, bool isClassMessage,
- SourceLocation lbrac, SourceLocation rbrac,
- QualType &ReturnType);
-
- /// CheckBooleanCondition - Diagnose problems involving the use of
- /// the given expression as a boolean condition (e.g. in an if
- /// statement). Also performs the standard function and array
- /// decays, possibly changing the input variable.
- ///
- /// \param Loc - A location associated with the condition, e.g. the
- /// 'if' keyword.
- /// \return true iff there were any errors
- bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
-
- virtual OwningExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- ExprArg SubExpr);
-
- /// DiagnoseAssignmentAsCondition - Given that an expression is
- /// being used as a boolean condition, warn if it's an assignment.
- void DiagnoseAssignmentAsCondition(Expr *E);
-
- /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
- bool CheckCXXBooleanCondition(Expr *&CondExpr);
-
- /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
- /// the specified width and sign. If an overflow occurs, detect it and emit
- /// the specified diagnostic.
- void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
- unsigned NewWidth, bool NewSign,
- SourceLocation Loc, unsigned DiagID);
-
- /// Checks that the Objective-C declaration is declared in the global scope.
- /// Emits an error and marks the declaration as invalid if it's not declared
- /// in the global scope.
- bool CheckObjCDeclScope(Decl *D);
-
- void InitBuiltinVaListType();
-
- /// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
- /// and reports the appropriate diagnostics. Returns false on success.
- /// Can optionally return the value of the expression.
- bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
-
- /// VerifyBitField - verifies that a bit field expression is an ICE and has
- /// the correct width, and that the field type is valid.
- /// Returns false on success.
- /// Can optionally return whether the bit-field is of width 0
- bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth,
- bool *ZeroWidth = 0);
-
- /// \name Code completion
- //@{
- virtual void CodeCompleteOrdinaryName(Scope *S,
- CodeCompletionContext CompletionContext);
- virtual void CodeCompleteExpression(Scope *S, QualType T);
- virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
- SourceLocation OpLoc,
- bool IsArrow);
- virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
- virtual void CodeCompleteCase(Scope *S);
- virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
- ExprTy **Args, unsigned NumArgs);
- virtual void CodeCompleteInitializer(Scope *S, DeclPtrTy D);
- virtual void CodeCompleteReturn(Scope *S);
- virtual void CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS);
-
- virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
- bool EnteringContext);
- virtual void CodeCompleteUsing(Scope *S);
- virtual void CodeCompleteUsingDirective(Scope *S);
- virtual void CodeCompleteNamespaceDecl(Scope *S);
- virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
- virtual void CodeCompleteOperatorName(Scope *S);
-
- virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
- bool InInterface);
- virtual void CodeCompleteObjCAtVisibility(Scope *S);
- virtual void CodeCompleteObjCAtStatement(Scope *S);
- virtual void CodeCompleteObjCAtExpression(Scope *S);
- virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
- virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
- DeclPtrTy *Methods,
- unsigned NumMethods);
- virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
- DeclPtrTy *Methods,
- unsigned NumMethods);
- virtual void CodeCompleteObjCMessageReceiver(Scope *S);
- virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents);
- virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents);
- virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents);
- virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
- unsigned NumProtocols);
- virtual void CodeCompleteObjCProtocolDecl(Scope *S);
- virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
- virtual void CodeCompleteObjCSuperclass(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- virtual void CodeCompleteObjCImplementationDecl(Scope *S);
- virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- virtual void CodeCompleteObjCImplementationCategory(Scope *S,
- IdentifierInfo *ClassName,
- SourceLocation ClassNameLoc);
- virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
- DeclPtrTy ObjCImpDecl);
- virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
- IdentifierInfo *PropertyName,
- DeclPtrTy ObjCImpDecl);
- virtual void CodeCompleteObjCMethodDecl(Scope *S,
- bool IsInstanceMethod,
- TypeTy *ReturnType,
- DeclPtrTy IDecl);
- virtual void CodeCompleteObjCMethodDeclSelector(Scope *S,
- bool IsInstanceMethod,
- bool AtParameterName,
- TypeTy *ReturnType,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents);
-
- //@}
-
- //===--------------------------------------------------------------------===//
- // Extra semantic analysis beyond the C type system
-
-public:
- SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
- unsigned ByteNo) const;
-
-private:
- bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
- bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
-
- bool CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall);
- bool CheckObjCString(Expr *Arg);
-
- Action::OwningExprResult CheckBuiltinFunctionCall(unsigned BuiltinID,
- CallExpr *TheCall);
- bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
- bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
- bool SemaBuiltinVAStart(CallExpr *TheCall);
- bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
- bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
-
-public:
- // Used by C++ template instantiation.
- Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
-
-private:
- bool SemaBuiltinPrefetch(CallExpr *TheCall);
- bool SemaBuiltinObjectSize(CallExpr *TheCall);
- bool SemaBuiltinLongjmp(CallExpr *TheCall);
- OwningExprResult SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult);
- bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
- llvm::APSInt &Result);
- bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
- bool HasVAListArg, unsigned format_idx,
- unsigned firstDataArg);
- void CheckPrintfString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
- const CallExpr *TheCall, bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg);
- void CheckNonNullArguments(const NonNullAttr *NonNull,
- const CallExpr *TheCall);
- void CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg);
- void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
- SourceLocation ReturnLoc);
- void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
- void CheckImplicitConversions(Expr *E);
-};
-
-//===--------------------------------------------------------------------===//
-// Typed version of Parser::ExprArg (smart pointer for wrapping Expr pointers).
-template <typename T>
-class ExprOwningPtr : public Action::ExprArg {
-public:
- ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {}
-
- void reset(T* p) { Action::ExprArg::operator=(p); }
- T* get() const { return static_cast<T*>(Action::ExprArg::get()); }
- T* take() { return static_cast<T*>(Action::ExprArg::take()); }
- T* release() { return take(); }
-
- T& operator*() const { return *get(); }
- T* operator->() const { return get(); }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index e110e3dfa471..e629f0fd35bf 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
@@ -22,6 +23,7 @@
#include "clang/AST/ExprCXX.h"
using namespace clang;
+using namespace sema;
/// A copy of Sema's enum without AR_delayed.
enum AccessResult {
@@ -132,10 +134,10 @@ struct EffectiveContext {
bool Dependent;
};
-/// Like Sema's AccessedEntity, but kindly lets us scribble all over
+/// Like sema:;AccessedEntity, but kindly lets us scribble all over
/// it.
-struct AccessTarget : public Sema::AccessedEntity {
- AccessTarget(const Sema::AccessedEntity &Entity)
+struct AccessTarget : public AccessedEntity {
+ AccessTarget(const AccessedEntity &Entity)
: AccessedEntity(Entity) {
initialize();
}
@@ -562,6 +564,130 @@ static AccessResult GetFriendKind(Sema &S,
return OnFailure;
}
+namespace {
+
+/// A helper class for checking for a friend which will grant access
+/// to a protected instance member.
+struct ProtectedFriendContext {
+ Sema &S;
+ const EffectiveContext &EC;
+ const CXXRecordDecl *NamingClass;
+ bool CheckDependent;
+ bool EverDependent;
+
+ /// The path down to the current base class.
+ llvm::SmallVector<const CXXRecordDecl*, 20> CurPath;
+
+ ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
+ const CXXRecordDecl *InstanceContext,
+ const CXXRecordDecl *NamingClass)
+ : S(S), EC(EC), NamingClass(NamingClass),
+ CheckDependent(InstanceContext->isDependentContext() ||
+ NamingClass->isDependentContext()),
+ EverDependent(false) {}
+
+ /// Check classes in the current path for friendship, starting at
+ /// the given index.
+ bool checkFriendshipAlongPath(unsigned I) {
+ assert(I < CurPath.size());
+ for (unsigned E = CurPath.size(); I != E; ++I) {
+ switch (GetFriendKind(S, EC, CurPath[I])) {
+ case AR_accessible: return true;
+ case AR_inaccessible: continue;
+ case AR_dependent: EverDependent = true; continue;
+ }
+ }
+ return false;
+ }
+
+ /// Perform a search starting at the given class.
+ ///
+ /// PrivateDepth is the index of the last (least derived) class
+ /// along the current path such that a notional public member of
+ /// the final class in the path would have access in that class.
+ bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
+ // If we ever reach the naming class, check the current path for
+ // friendship. We can also stop recursing because we obviously
+ // won't find the naming class there again.
+ if (Cur == NamingClass)
+ return checkFriendshipAlongPath(PrivateDepth);
+
+ if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
+ EverDependent = true;
+
+ // Recurse into the base classes.
+ for (CXXRecordDecl::base_class_const_iterator
+ I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
+
+ // If this is private inheritance, then a public member of the
+ // base will not have any access in classes derived from Cur.
+ unsigned BasePrivateDepth = PrivateDepth;
+ if (I->getAccessSpecifier() == AS_private)
+ BasePrivateDepth = CurPath.size() - 1;
+
+ const CXXRecordDecl *RD;
+
+ QualType T = I->getType();
+ if (const RecordType *RT = T->getAs<RecordType>()) {
+ RD = cast<CXXRecordDecl>(RT->getDecl());
+ } else if (const InjectedClassNameType *IT
+ = T->getAs<InjectedClassNameType>()) {
+ RD = IT->getDecl();
+ } else {
+ assert(T->isDependentType() && "non-dependent base wasn't a record?");
+ EverDependent = true;
+ continue;
+ }
+
+ // Recurse. We don't need to clean up if this returns true.
+ CurPath.push_back(RD);
+ if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
+ return true;
+ CurPath.pop_back();
+ }
+
+ return false;
+ }
+
+ bool findFriendship(const CXXRecordDecl *Cur) {
+ assert(CurPath.empty());
+ CurPath.push_back(Cur);
+ return findFriendship(Cur, 0);
+ }
+};
+}
+
+/// Search for a class P that EC is a friend of, under the constraint
+/// InstanceContext <= P <= NamingClass
+/// and with the additional restriction that a protected member of
+/// NamingClass would have some natural access in P.
+///
+/// That second condition isn't actually quite right: the condition in
+/// the standard is whether the target would have some natural access
+/// in P. The difference is that the target might be more accessible
+/// along some path not passing through NamingClass. Allowing that
+/// introduces two problems:
+/// - It breaks encapsulation because you can suddenly access a
+/// forbidden base class's members by subclassing it elsewhere.
+/// - It makes access substantially harder to compute because it
+/// breaks the hill-climbing algorithm: knowing that the target is
+/// accessible in some base class would no longer let you change
+/// the question solely to whether the base class is accessible,
+/// because the original target might have been more accessible
+/// because of crazy subclassing.
+/// So we don't implement that.
+static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
+ const CXXRecordDecl *InstanceContext,
+ const CXXRecordDecl *NamingClass) {
+ assert(InstanceContext->getCanonicalDecl() == InstanceContext);
+ assert(NamingClass->getCanonicalDecl() == NamingClass);
+
+ ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
+ if (PRC.findFriendship(InstanceContext)) return AR_accessible;
+ if (PRC.EverDependent) return AR_dependent;
+ return AR_inaccessible;
+}
+
static AccessResult HasAccess(Sema &S,
const EffectiveContext &EC,
const CXXRecordDecl *NamingClass,
@@ -629,20 +755,25 @@ static AccessResult HasAccess(Sema &S,
}
}
- if (!NamingClass->hasFriends())
- return OnFailure;
-
- // Don't consider friends if we're under the [class.protected]
- // restriction, above.
+ // [M3] and [B3] say that, if the target is protected in N, we grant
+ // access if the access occurs in a friend or member of some class P
+ // that's a subclass of N and where the target has some natural
+ // access in P. The 'member' aspect is easy to handle because P
+ // would necessarily be one of the effective-context records, and we
+ // address that above. The 'friend' aspect is completely ridiculous
+ // to implement because there are no restrictions at all on P
+ // *unless* the [class.protected] restriction applies. If it does,
+ // however, we should ignore whether the naming class is a friend,
+ // and instead rely on whether any potential P is a friend.
if (Access == AS_protected && Target.hasInstanceContext()) {
const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
if (!InstanceContext) return AR_dependent;
-
- switch (IsDerivedFromInclusive(InstanceContext, NamingClass)) {
- case AR_accessible: break;
+ switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
+ case AR_accessible: return AR_accessible;
case AR_inaccessible: return OnFailure;
case AR_dependent: return AR_dependent;
}
+ llvm_unreachable("impossible friendship kind");
}
switch (GetFriendKind(S, EC, NamingClass)) {
@@ -799,6 +930,57 @@ static CXXBasePath *FindBestPath(Sema &S,
return BestPath;
}
+/// Given that an entity has protected natural access, check whether
+/// access might be denied because of the protected member access
+/// restriction.
+///
+/// \return true if a note was emitted
+static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
+ AccessTarget &Target) {
+ // Only applies to instance accesses.
+ if (!Target.hasInstanceContext())
+ return false;
+ assert(Target.isMemberAccess());
+ NamedDecl *D = Target.getTargetDecl();
+
+ const CXXRecordDecl *DeclaringClass = Target.getDeclaringClass();
+ DeclaringClass = DeclaringClass->getCanonicalDecl();
+
+ for (EffectiveContext::record_iterator
+ I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
+ const CXXRecordDecl *ECRecord = *I;
+ switch (IsDerivedFromInclusive(ECRecord, DeclaringClass)) {
+ case AR_accessible: break;
+ case AR_inaccessible: continue;
+ case AR_dependent: continue;
+ }
+
+ // The effective context is a subclass of the declaring class.
+ // If that class isn't a superclass of the instance context,
+ // then the [class.protected] restriction applies.
+
+ // To get this exactly right, this might need to be checked more
+ // holistically; it's not necessarily the case that gaining
+ // access here would grant us access overall.
+
+ const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
+ assert(InstanceContext && "diagnosing dependent access");
+
+ switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
+ case AR_accessible: continue;
+ case AR_dependent: continue;
+ case AR_inaccessible:
+ S.Diag(D->getLocation(), diag::note_access_protected_restricted)
+ << (InstanceContext != Target.getNamingClass()->getCanonicalDecl())
+ << S.Context.getTypeDeclType(InstanceContext)
+ << S.Context.getTypeDeclType(ECRecord);
+ return true;
+ }
+ }
+
+ return false;
+}
+
/// Diagnose the path which caused the given declaration or base class
/// to become inaccessible.
static void DiagnoseAccessPath(Sema &S,
@@ -817,6 +999,10 @@ static void DiagnoseAccessPath(Sema &S,
if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
case AR_inaccessible: {
+ if (Access == AS_protected &&
+ TryDiagnoseProtectedAccess(S, EC, Entity))
+ return;
+
S.Diag(D->getLocation(), diag::note_access_natural)
<< (unsigned) (Access == AS_protected)
<< /*FIXME: not implicitly*/ 0;
@@ -1033,7 +1219,7 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
// access control.
if (S.CurContext->isFileContext() && S.ParsingDeclDepth) {
S.DelayedDiagnostics.push_back(
- Sema::DelayedDiagnostic::makeAccess(Loc, Entity));
+ DelayedDiagnostic::makeAccess(Loc, Entity));
return Sema::AR_delayed;
}
@@ -1266,7 +1452,7 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
Found.getAccess() == AS_public)
return AR_accessible;
- OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
+ OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
CXXRecordDecl *NamingClass = Ovl->getNamingClass();
AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 69f27b0ada7d..0921156b932f 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -12,8 +12,9 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
@@ -62,18 +63,30 @@ namespace {
/// alignment to the previous value. If \arg Name is non-zero then
/// the first such named record is popped, otherwise the top record
/// is popped. Returns true if the pop succeeded.
- bool pop(IdentifierInfo *Name);
+ bool pop(IdentifierInfo *Name, bool IsReset);
};
} // end anonymous namespace.
-bool PragmaPackStack::pop(IdentifierInfo *Name) {
- if (Stack.empty())
- return false;
-
+bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
// If name is empty just pop top.
if (!Name) {
- Alignment = Stack.back().Alignment;
- Stack.pop_back();
+ // An empty stack is a special case...
+ if (Stack.empty()) {
+ // If this isn't a reset, it is always an error.
+ if (!IsReset)
+ return false;
+
+ // Otherwise, it is an error only if some alignment has been set.
+ if (!Alignment)
+ return false;
+
+ // Otherwise, reset to the default alignment.
+ Alignment = 0;
+ } else {
+ Alignment = Stack.back().Alignment;
+ Stack.pop_back();
+ }
+
return true;
}
@@ -108,9 +121,11 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
// Otherwise, check to see if we need a max field alignment attribute.
if (unsigned Alignment = Stack->getAlignment()) {
if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
- RD->addAttr(::new (Context) AlignMac68kAttr());
+ RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
else
- RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
+ RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+ Context,
+ Alignment * 8));
}
}
@@ -122,13 +137,10 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
- // Reset just pops the top of the stack.
- if (Kind == Action::POAK_Reset) {
- // Do the pop.
- if (!Context->pop(0)) {
- // If a name was specified then failure indicates the name
- // wasn't found. Otherwise failure indicates the stack was
- // empty.
+ // Reset just pops the top of the stack, or resets the current alignment to
+ // default.
+ if (Kind == Sema::POAK_Reset) {
+ if (!Context->pop(0, /*IsReset=*/true)) {
Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
<< "stack empty";
}
@@ -188,7 +200,6 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
!(Val == 0 || Val.isPowerOf2()) ||
Val.getZExtValue() > 16) {
Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
- Alignment->Destroy(Context);
return; // Ignore
}
@@ -201,11 +212,11 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
switch (Kind) {
- case Action::PPK_Default: // pack([n])
+ case Sema::PPK_Default: // pack([n])
Context->setAlignment(AlignmentVal);
break;
- case Action::PPK_Show: // pack(show)
+ case Sema::PPK_Show: // pack(show)
// Show the current alignment, making sure to show the right value
// for the default.
AlignmentVal = Context->getAlignment();
@@ -218,21 +229,21 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
break;
- case Action::PPK_Push: // pack(push [, id] [, [n])
+ case Sema::PPK_Push: // pack(push [, id] [, [n])
Context->push(Name);
// Set the new alignment if specified.
if (Alignment)
Context->setAlignment(AlignmentVal);
break;
- case Action::PPK_Pop: // pack(pop [, id] [, n])
+ case Sema::PPK_Pop: // pack(pop [, id] [, n])
// MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
// "#pragma pack(pop, identifier, n) is undefined"
if (Alignment && Name)
Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
// Do the pop.
- if (!Context->pop(Name)) {
+ if (!Context->pop(Name, /*IsReset=*/false)) {
// If a name was specified then failure indicates the name
// wasn't found. Otherwise failure indicates the stack was
// empty.
@@ -277,6 +288,80 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
continue;
}
- VD->addAttr(::new (Context) UnusedAttr());
+ VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
+ }
+}
+
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+ SourceLocation> > VisStack;
+
+void Sema::AddPushedVisibilityAttribute(Decl *D) {
+ if (!VisContext)
+ return;
+
+ if (D->hasAttr<VisibilityAttr>())
+ return;
+
+ VisStack *Stack = static_cast<VisStack*>(VisContext);
+ VisibilityAttr::VisibilityType type = Stack->back().first;
+ SourceLocation loc = Stack->back().second;
+
+ D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
+}
+
+/// FreeVisContext - Deallocate and null out VisContext.
+void Sema::FreeVisContext() {
+ delete static_cast<VisStack*>(VisContext);
+ VisContext = 0;
+}
+
+static void PushPragmaVisibility(Sema &S, VisibilityAttr::VisibilityType type,
+ SourceLocation loc) {
+ // Put visibility on stack.
+ if (!S.VisContext)
+ S.VisContext = new VisStack;
+
+ VisStack *Stack = static_cast<VisStack*>(S.VisContext);
+ Stack->push_back(std::make_pair(type, loc));
+}
+
+void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+ SourceLocation PragmaLoc) {
+ if (IsPush) {
+ // Compute visibility to use.
+ VisibilityAttr::VisibilityType type;
+ if (VisType->isStr("default"))
+ type = VisibilityAttr::Default;
+ else if (VisType->isStr("hidden"))
+ type = VisibilityAttr::Hidden;
+ else if (VisType->isStr("internal"))
+ type = VisibilityAttr::Hidden; // FIXME
+ else if (VisType->isStr("protected"))
+ type = VisibilityAttr::Protected;
+ else {
+ Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
+ VisType->getName();
+ return;
+ }
+ PushPragmaVisibility(*this, type, PragmaLoc);
+ } else {
+ PopPragmaVisibility();
+ }
+}
+
+void Sema::PushVisibilityAttr(const VisibilityAttr *Attr) {
+ PushPragmaVisibility(*this, Attr->getVisibility(), Attr->getLocation());
+}
+
+void Sema::PopPragmaVisibility() {
+ // Pop visibility from stack, if there is one on the stack.
+ if (VisContext) {
+ VisStack *Stack = static_cast<VisStack*>(VisContext);
+
+ Stack->pop_back();
+ // To simplify the implementation, never keep around an empty stack.
+ if (Stack->empty())
+ FreeVisContext();
}
+ // FIXME: Add diag for pop without push.
}
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index b8e27e7b7285..21b1a73aa3bc 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
@@ -43,16 +43,16 @@ static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
const SourceRange &DestRange,
- CastExpr::CastKind &Kind);
+ CastKind &Kind);
static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
const SourceRange &DestRange,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
@@ -73,54 +73,54 @@ static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
CanQualType DestType, bool CStyle,
const SourceRange &OpRange,
QualType OrigSrcType,
QualType OrigDestType, unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
QualType SrcType,
QualType DestType,bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind);
+ CastKind &Kind);
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath);
+ CastKind &Kind,
+ CXXCastPath &BasePath);
static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, unsigned &msg);
static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind);
+ CastKind &Kind);
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
- SourceLocation LAngleBracketLoc, TypeTy *Ty,
+ SourceLocation LAngleBracketLoc, ParsedType Ty,
SourceLocation RAngleBracketLoc,
- SourceLocation LParenLoc, ExprArg E,
+ SourceLocation LParenLoc, Expr *E,
SourceLocation RParenLoc) {
TypeSourceInfo *DestTInfo;
@@ -133,11 +133,10 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
SourceRange(LParenLoc, RParenLoc));
}
-Action::OwningExprResult
+ExprResult
Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
- TypeSourceInfo *DestTInfo, ExprArg E,
+ TypeSourceInfo *DestTInfo, Expr *Ex,
SourceRange AngleBrackets, SourceRange Parens) {
- Expr *Ex = E.takeAs<Expr>();
QualType DestType = DestTInfo->getType();
SourceRange OpRange(OpLoc, Parens.getEnd());
@@ -153,39 +152,39 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
case tok::kw_const_cast:
if (!TypeDependent)
CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
- return Owned(new (Context) CXXConstCastExpr(
+ return Owned(CXXConstCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- Ex, DestTInfo, OpLoc));
+ Ex, DestTInfo, OpLoc));
case tok::kw_dynamic_cast: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (!TypeDependent)
CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
- return Owned(new (Context)CXXDynamicCastExpr(
+ return Owned(CXXDynamicCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- Kind, Ex, BasePath, DestTInfo,
- OpLoc));
+ Kind, Ex, &BasePath, DestTInfo,
+ OpLoc));
}
case tok::kw_reinterpret_cast: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+ CastKind Kind = CK_Unknown;
if (!TypeDependent)
CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
- return Owned(new (Context) CXXReinterpretCastExpr(
+ return Owned(CXXReinterpretCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- Kind, Ex, CXXBaseSpecifierArray(),
+ Kind, Ex, 0,
DestTInfo, OpLoc));
}
case tok::kw_static_cast: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (!TypeDependent)
CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
- return Owned(new (Context) CXXStaticCastExpr(
+ return Owned(CXXStaticCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
- Kind, Ex, BasePath,
- DestTInfo, OpLoc));
+ Kind, Ex, &BasePath,
+ DestTInfo, OpLoc));
}
}
@@ -197,7 +196,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
/// the same kind of pointer (plain or to-member). Unlike the Sema function,
/// this one doesn't care if the two pointers-to-member don't point into the
/// same class. This is because CastsAwayConstness doesn't care.
-bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
+static bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
const PointerType *T1PtrType = T1->getAs<PointerType>(),
*T2PtrType = T2->getAs<PointerType>();
if (T1PtrType && T2PtrType) {
@@ -307,8 +306,8 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
static void
CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange,
- const SourceRange &DestRange, CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ const SourceRange &DestRange, CastKind &Kind,
+ CXXCastPath &BasePath) {
QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
DestType = Self.Context.getCanonicalType(DestType);
@@ -396,6 +395,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
// C++ 5.2.7p3: If the type of v is the same as the required result type,
// [except for cv].
if (DestRecord == SrcRecord) {
+ Kind = CK_NoOp;
return;
}
@@ -407,7 +407,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
&BasePath))
return;
- Kind = CastExpr::CK_DerivedToBase;
+ Kind = CK_DerivedToBase;
// If we are casting to or through a virtual base class, we need a
// vtable.
@@ -428,7 +428,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
cast<CXXRecordDecl>(SrcRecord->getDecl()));
// Done. Everything else is run-time checks.
- Kind = CastExpr::CK_Dynamic;
+ Kind = CK_Dynamic;
}
/// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
@@ -457,7 +457,7 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
void
CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange, const SourceRange &DestRange,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
if (!DestType->isLValueReferenceType())
Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
@@ -475,13 +475,13 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
/// implicit conversions explicit and getting rid of data loss warnings.
void
CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
- const SourceRange &OpRange, CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ const SourceRange &OpRange, CastKind &Kind,
+ CXXCastPath &BasePath) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
if (DestType->isVoidType()) {
- Kind = CastExpr::CK_ToVoid;
+ Kind = CK_ToVoid;
return;
}
@@ -493,6 +493,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
Kind, BasePath) != TC_Success && msg != 0)
Self.Diag(OpRange.getBegin(), msg) << CT_Static
<< SrcExpr->getType() << DestType << OpRange;
+ else if (Kind == CK_Unknown || Kind == CK_BitCast)
+ Self.CheckCastAlign(SrcExpr, DestType, OpRange);
}
/// TryStaticCast - Check if a static cast can be performed, and do so if
@@ -501,8 +503,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange, unsigned &msg,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ CastKind &Kind,
+ CXXCastPath &BasePath) {
// The order the tests is not entirely arbitrary. There is one conversion
// that can be handled in two different ways. Given:
// struct A {};
@@ -532,7 +534,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, msg);
if (tcr != TC_NotApplicable) {
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
return tcr;
}
@@ -567,7 +569,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
if (SrcType->isComplexType() || SrcType->isVectorType()) {
// Fall through - these cannot be converted.
} else if (SrcType->isArithmeticType() || SrcType->isEnumeralType()) {
- Kind = CastExpr::CK_IntegralCast;
+ Kind = CK_IntegralCast;
return TC_Success;
}
}
@@ -602,19 +604,19 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
msg = diag::err_bad_cxx_cast_const_away;
return TC_Failed;
}
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return TC_Success;
}
}
else if (DestType->isObjCObjectPointerType()) {
// allow both c-style cast and static_cast of objective-c pointers as
// they are pervasive.
- Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+ Kind = CK_AnyPointerToObjCPointerCast;
return TC_Success;
}
else if (CStyle && DestType->isBlockPointerType()) {
// allow c-style cast of void * to block pointers.
- Kind = CastExpr::CK_AnyPointerToBlockPointerCast;
+ Kind = CK_AnyPointerToBlockPointerCast;
return TC_Success;
}
}
@@ -645,9 +647,10 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
// this is the only cast possibility, so we issue an error if we fail now.
// FIXME: Should allow casting away constness if CStyle.
bool DerivedToBase;
+ bool ObjCConversion;
if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(),
SrcExpr->getType(), R->getPointeeType(),
- DerivedToBase) <
+ DerivedToBase, ObjCConversion) <
Sema::Ref_Compatible_With_Added_Qualification) {
msg = diag::err_bad_lvalue_to_rvalue_cast;
return TC_Failed;
@@ -662,8 +665,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
TryCastResult
TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, const SourceRange &OpRange,
- unsigned &msg, CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ unsigned &msg, CastKind &Kind,
+ CXXCastPath &BasePath) {
// C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be
// cast to type "reference to cv2 D", where D is a class derived from B,
// if a valid standard conversion from "pointer to D" to "pointer to B"
@@ -697,8 +700,8 @@ TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
TryCastResult
TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
bool CStyle, const SourceRange &OpRange,
- unsigned &msg, CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ unsigned &msg, CastKind &Kind,
+ CXXCastPath &BasePath) {
// C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class
// type, can be converted to an rvalue of type "pointer to cv2 D", where D
// is a class derived from B, if a valid standard conversion from "pointer
@@ -732,7 +735,7 @@ TryCastResult
TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
bool CStyle, const SourceRange &OpRange, QualType OrigSrcType,
QualType OrigDestType, unsigned &msg,
- CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) {
+ CastKind &Kind, CXXCastPath &BasePath) {
// We can only work with complete types. But don't complain if it doesn't work
if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) ||
Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0)))
@@ -824,7 +827,7 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
}
Self.BuildBasePathArray(Paths, BasePath);
- Kind = CastExpr::CK_BaseToDerived;
+ Kind = CK_BaseToDerived;
return TC_Success;
}
@@ -839,8 +842,8 @@ TryCastResult
TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
- unsigned &msg, CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath) {
+ unsigned &msg, CastKind &Kind,
+ CXXCastPath &BasePath) {
const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
if (!DestMemPtr)
return TC_NotApplicable;
@@ -900,7 +903,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
}
if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(),
- DestType, SrcType,
+ DestClass, SrcClass,
Paths.front(),
diag::err_upcast_to_inaccessible_base)) {
msg = 0;
@@ -927,7 +930,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
}
Self.BuildBasePathArray(Paths, BasePath);
- Kind = CastExpr::CK_DerivedToBaseMemberPointer;
+ Kind = CK_DerivedToBaseMemberPointer;
return TC_Success;
}
@@ -939,7 +942,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
TryCastResult
TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
bool CStyle, const SourceRange &OpRange, unsigned &msg,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
if (DestType->isRecordType()) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
diag::err_bad_dynamic_cast_incomplete)) {
@@ -961,18 +964,17 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
(CStyle || !DestType->isReferenceType()))
return TC_NotApplicable;
- Sema::OwningExprResult Result
- = InitSeq.Perform(Self, Entity, InitKind,
- Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
+ ExprResult Result
+ = InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExpr, 1));
if (Result.isInvalid()) {
msg = 0;
return TC_Failed;
}
if (InitSeq.isConstructorInitialization())
- Kind = CastExpr::CK_ConstructorConversion;
+ Kind = CK_ConstructorConversion;
else
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
SrcExpr = Result.takeAs<Expr>();
return TC_Success;
@@ -1051,7 +1053,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
bool IsLValueCast = false;
DestType = Self.Context.getCanonicalType(DestType);
@@ -1097,8 +1099,15 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
return TC_Failed;
}
+ // Don't allow casting between member pointers of different sizes.
+ if (Self.Context.getTypeSize(DestMemPtr) !=
+ Self.Context.getTypeSize(SrcMemPtr)) {
+ msg = diag::err_bad_cxx_cast_member_pointer_size;
+ return TC_Failed;
+ }
+
// A valid member pointer cast.
- Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast;
+ Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
return TC_Success;
}
@@ -1113,7 +1122,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
msg = diag::err_bad_reinterpret_cast_small_int;
return TC_Failed;
}
- Kind = CastExpr::CK_PointerToIntegral;
+ Kind = CK_PointerToIntegral;
return TC_Success;
}
@@ -1132,7 +1141,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
// If both types have the same size, we can successfully cast.
if (Self.Context.getTypeSize(SrcType)
== Self.Context.getTypeSize(DestType)) {
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return TC_Success;
}
@@ -1163,7 +1172,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
// to the same type. However, the behavior of compilers is pretty consistent
// on this point: allow same-type conversion if the involved types are
// pointers, disallow otherwise.
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
return TC_Success;
}
@@ -1176,7 +1185,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
msg = diag::err_bad_reinterpret_cast_small_int;
return TC_Failed;
}
- Kind = CastExpr::CK_PointerToIntegral;
+ Kind = CK_PointerToIntegral;
return TC_Success;
}
@@ -1184,7 +1193,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
assert(destIsPtr && "One type must be a pointer");
// C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
// converted to a pointer.
- Kind = CastExpr::CK_IntegralToPointer;
+ Kind = CK_IntegralToPointer;
return TC_Success;
}
@@ -1209,13 +1218,13 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
// Any pointer can be cast to an Objective-C pointer type with a C-style
// cast.
if (CStyle && DestType->isObjCObjectPointerType()) {
- Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+ Kind = CK_AnyPointerToObjCPointerCast;
return TC_Success;
}
// Not casting away constness, so the only remaining check is for compatible
// pointer categories.
- Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast;
+ Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
if (SrcType->isFunctionPointerType()) {
if (DestType->isFunctionPointerType()) {
@@ -1252,14 +1261,14 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
bool
Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath,
+ CastKind &Kind,
+ CXXCastPath &BasePath,
bool FunctionalStyle) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
if (CastTy->isVoidType()) {
- Kind = CastExpr::CK_ToVoid;
+ Kind = CK_ToVoid;
return false;
}
@@ -1285,7 +1294,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
msg);
if (tcr == TC_Success)
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
if (tcr == TC_NotApplicable) {
// ... or if that is not possible, a static_cast, ignoring const, ...
@@ -1301,6 +1310,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
if (tcr != TC_Success && msg != 0)
Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
<< CastExpr->getType() << CastTy << R;
+ else if (Kind == CK_Unknown || Kind == CK_BitCast)
+ CheckCastAlign(CastExpr, CastTy, R);
return tcr != TC_Success;
}
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index f56573a8de26..631308eebb04 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -11,14 +11,14 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -283,7 +283,7 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
SourceLocation IdLoc,
IdentifierInfo &II,
- TypeTy *ObjectTypePtr) {
+ ParsedType ObjectTypePtr) {
QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
@@ -416,7 +416,17 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
ObjectTypeSearchedInScope = true;
}
- } else if (isDependent) {
+ } else if (!isDependent) {
+ // Perform unqualified name lookup in the current scope.
+ LookupName(Found, S);
+ }
+
+ // If we performed lookup into a dependent context and did not find anything,
+ // that's fine: just build a dependent nested-name-specifier.
+ if (Found.empty() && isDependent &&
+ !(LookupCtx && LookupCtx->isRecord() &&
+ (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() ||
+ !cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) {
// Don't speculate if we're just trying to improve error recovery.
if (ErrorRecoveryLookup)
return 0;
@@ -429,11 +439,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
return NestedNameSpecifier::Create(Context, &II);
return NestedNameSpecifier::Create(Context, Prefix, &II);
- } else {
- // Perform unqualified name lookup in the current scope.
- LookupName(Found, S);
- }
-
+ }
+
// FIXME: Deal with ambiguities cleanly.
if (Found.empty() && !ErrorRecoveryLookup) {
@@ -560,10 +567,10 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II,
- TypeTy *ObjectTypePtr,
+ ParsedType ObjectTypePtr,
bool EnteringContext) {
return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
- QualType::getFromOpaquePtr(ObjectTypePtr),
+ GetTypeFromParser(ObjectTypePtr),
/*ScopeLookupResult=*/0, EnteringContext,
false);
}
@@ -575,21 +582,20 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
///
/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
- IdentifierInfo &II, TypeTy *ObjectType,
+ IdentifierInfo &II, ParsedType ObjectType,
bool EnteringContext) {
return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
- II, QualType::getFromOpaquePtr(ObjectType),
+ II, GetTypeFromParser(ObjectType),
/*ScopeLookupResult=*/0, EnteringContext,
true);
}
Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
const CXXScopeSpec &SS,
- TypeTy *Ty,
+ ParsedType Ty,
SourceRange TypeRange,
SourceLocation CCLoc) {
- NestedNameSpecifier *Prefix
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+ NestedNameSpecifier *Prefix = SS.getScopeRep();
QualType T = GetTypeFromParser(Ty);
return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
T.getTypePtr());
@@ -620,7 +626,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
case NestedNameSpecifier::Namespace:
// These are always namespace scopes. We never want to enter a
// namespace scope from anything but a file context.
- return CurContext->getLookupContext()->isFileContext();
+ return CurContext->getRedeclContext()->isFileContext();
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::TypeSpec:
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 7a39f058c5ec..a0b4b988dbeb 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -12,10 +12,13 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Analysis/Analyses/FormatString.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
@@ -26,12 +29,12 @@
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include <limits>
using namespace clang;
+using namespace sema;
/// getLocationOfStringLiteralByte - Return a source location that points to the
/// specified byte of the specified string literal.
@@ -122,9 +125,9 @@ bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) {
return false;
}
-Action::OwningExprResult
+ExprResult
Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
- OwningExprResult TheCallResult(Owned(TheCall));
+ ExprResult TheCallResult(Owned(TheCall));
switch (BuiltinID) {
case Builtin::BI__builtin___CFStringMakeConstantString:
@@ -298,6 +301,10 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
unsigned i = 0, l = 0, u = 0;
switch (BuiltinID) {
default: return false;
+ case ARM::BI__builtin_arm_ssat: i = 1; l = 1; u = 31; break;
+ case ARM::BI__builtin_arm_usat: i = 1; u = 31; break;
+ case ARM::BI__builtin_arm_vcvtr_f:
+ case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
#define GET_NEON_IMMEDIATE_CHECK
#include "clang/Basic/arm_neon.inc"
#undef GET_NEON_IMMEDIATE_CHECK
@@ -311,9 +318,9 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
unsigned Val = Result.getZExtValue();
if (Val < l || Val > (u + l))
return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
- << llvm::utostr(l) << llvm::utostr(u+l)
- << TheCall->getArg(i)->getSourceRange();
+ << l << u+l << TheCall->getArg(i)->getSourceRange();
+ // FIXME: VFP Intrinsics should error if VFP not present.
return false;
}
@@ -334,16 +341,22 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
// Printf checking.
if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
- if (CheckablePrintfAttr(Format, TheCall)) {
+ const bool b = Format->getType() == "scanf";
+ if (b || CheckablePrintfAttr(Format, TheCall)) {
bool HasVAListArg = Format->getFirstArg() == 0;
- CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
- HasVAListArg ? 0 : Format->getFirstArg() - 1);
+ CheckPrintfScanfArguments(TheCall, HasVAListArg,
+ Format->getFormatIdx() - 1,
+ HasVAListArg ? 0 : Format->getFirstArg() - 1,
+ !b);
}
}
- for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
- NonNull = NonNull->getNext<NonNullAttr>())
- CheckNonNullArguments(NonNull, TheCall);
+ specific_attr_iterator<NonNullAttr>
+ i = FDecl->specific_attr_begin<NonNullAttr>(),
+ e = FDecl->specific_attr_end<NonNullAttr>();
+
+ for (; i != e; ++i)
+ CheckNonNullArguments(*i, TheCall);
return false;
}
@@ -362,12 +375,13 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
if (!Ty->isBlockPointerType())
return false;
- if (!CheckablePrintfAttr(Format, TheCall))
+ const bool b = Format->getType() == "scanf";
+ if (!b && !CheckablePrintfAttr(Format, TheCall))
return false;
bool HasVAListArg = Format->getFirstArg() == 0;
- CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
- HasVAListArg ? 0 : Format->getFirstArg() - 1);
+ CheckPrintfScanfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
+ HasVAListArg ? 0 : Format->getFirstArg() - 1, !b);
return false;
}
@@ -380,8 +394,8 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
///
/// This function goes through and does final semantic checking for these
/// builtins,
-Sema::OwningExprResult
-Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
+ExprResult
+Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
CallExpr *TheCall = (CallExpr *)TheCallResult.get();
DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
@@ -415,6 +429,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
return ExprError();
}
+ // The majority of builtins return a value, but a few have special return
+ // types, so allow them to override appropriately below.
+ QualType ResultType = ValType;
+
// We need to figure out which concrete builtin this maps onto. For example,
// __sync_fetch_and_add with a 2 byte object turns into
// __sync_fetch_and_add_2.
@@ -483,11 +501,13 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
case Builtin::BI__sync_bool_compare_and_swap:
BuiltinIndex = 11;
NumFixed = 2;
+ ResultType = Context.BoolTy;
break;
case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break;
case Builtin::BI__sync_lock_release:
BuiltinIndex = 13;
NumFixed = 0;
+ ResultType = Context.VoidTy;
break;
}
@@ -508,19 +528,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
FunctionDecl *NewBuiltinDecl =
cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID,
TUScope, false, DRE->getLocStart()));
- const FunctionProtoType *BuiltinFT =
- NewBuiltinDecl->getType()->getAs<FunctionProtoType>();
-
- QualType OrigValType = ValType;
- ValType = BuiltinFT->getArgType(0)->getAs<PointerType>()->getPointeeType();
-
- // If the first type needs to be converted (e.g. void** -> int*), do it now.
- if (BuiltinFT->getArgType(0) != FirstArg->getType()) {
- ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), CastExpr::CK_BitCast);
- TheCall->setArg(0, FirstArg);
- }
- // Next, walk the valid ones promoting to the right type.
+ // The first argument --- the pointer --- has a fixed type; we
+ // deduce the types of the rest of the arguments accordingly. Walk
+ // the remaining arguments, converting them to the deduced value type.
for (unsigned i = 0; i != NumFixed; ++i) {
Expr *Arg = TheCall->getArg(i+1);
@@ -529,14 +540,13 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
Arg = ICE->getSubExpr();
ICE->setSubExpr(0);
- ICE->Destroy(Context);
TheCall->setArg(i+1, Arg);
}
// GCC does an implicit conversion to the pointer or integer ValType. This
// can fail in some cases (1i -> int**), check for this error case now.
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
return ExprError();
@@ -546,7 +556,7 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
// pass in 42. The 42 gets converted to char. This is even more strange
// for things like 45.123 -> char, etc.
// FIXME: Do this check.
- ImpCastExprToType(Arg, ValType, Kind);
+ ImpCastExprToType(Arg, ValType, Kind, VK_RValue, &BasePath);
TheCall->setArg(i+1, Arg);
}
@@ -560,28 +570,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
UsualUnaryConversions(PromotedCall);
TheCall->setCallee(PromotedCall);
- // Change the result type of the call to match the result type of the decl.
- TheCall->setType(NewBuiltinDecl->getCallResultType());
-
- // If the value type was converted to an integer when processing the
- // arguments (e.g. void* -> int), we need to convert the result back.
- if (!Context.hasSameUnqualifiedType(ValType, OrigValType)) {
- Expr *E = TheCallResult.takeAs<Expr>();
-
- assert(ValType->isIntegerType() &&
- "We always convert atomic operation values to integers.");
- // FIXME: Handle floating point value type here too.
- CastExpr::CastKind Kind;
- if (OrigValType->isIntegerType())
- Kind = CastExpr::CK_IntegralCast;
- else if (OrigValType->hasPointerRepresentation())
- Kind = CastExpr::CK_IntegralToPointer;
- else
- llvm_unreachable("Unhandled original value type!");
-
- ImpCastExprToType(E, OrigValType, Kind);
- return Owned(E);
- }
+ // Change the result type of the call to match the original value type. This
+ // is arbitrary, but the codegen for these builtins ins design to handle it
+ // gracefully.
+ TheCall->setType(ResultType);
return move(TheCallResult);
}
@@ -604,16 +596,11 @@ bool Sema::CheckObjCString(Expr *Arg) {
return true;
}
- const char *Data = Literal->getStrData();
- unsigned Length = Literal->getByteLength();
-
- for (unsigned i = 0; i < Length; ++i) {
- if (!Data[i]) {
- Diag(getLocationOfStringLiteralByte(Literal, i),
- diag::warn_cfstring_literal_contains_nul_character)
- << Arg->getSourceRange();
- break;
- }
+ size_t NulPos = Literal->getString().find('\0');
+ if (NulPos != llvm::StringRef::npos) {
+ Diag(getLocationOfStringLiteralByte(Literal, NulPos),
+ diag::warn_cfstring_literal_contains_nul_character)
+ << Arg->getSourceRange();
}
return false;
@@ -753,7 +740,6 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
"promotion from float to double is the only expected cast here");
Cast->setSubExpr(0);
- Cast->Destroy(Context);
TheCall->setArg(NumArgs-1, CastArg);
OrigArg = CastArg;
}
@@ -764,7 +750,7 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
// This is declared to take (...), so we have to check everything.
-Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
if (TheCall->getNumArgs() < 2)
return ExprError(Diag(TheCall->getLocEnd(),
diag::err_typecheck_call_too_few_args_at_least)
@@ -797,7 +783,7 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
// with mask. If so, verify that RHS is an integer vector type with the
// same number of elts as lhs.
if (TheCall->getNumArgs() == 2) {
- if (!RHSType->isIntegerType() ||
+ if (!RHSType->hasIntegerRepresentation() ||
RHSType->getAs<VectorType>()->getNumElements() != numElements)
Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
<< SourceRange(TheCall->getArg(1)->getLocStart(),
@@ -941,29 +927,31 @@ bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) {
// Handle i > 1 ? "x" : "y", recursivelly
bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg) {
+ unsigned format_idx, unsigned firstDataArg,
+ bool isPrintf) {
+
if (E->isTypeDependent() || E->isValueDependent())
return false;
switch (E->getStmtClass()) {
case Stmt::ConditionalOperatorClass: {
const ConditionalOperator *C = cast<ConditionalOperator>(E);
- return SemaCheckStringLiteral(C->getTrueExpr(), TheCall,
- HasVAListArg, format_idx, firstDataArg)
- && SemaCheckStringLiteral(C->getRHS(), TheCall,
- HasVAListArg, format_idx, firstDataArg);
+ return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg,
+ format_idx, firstDataArg, isPrintf)
+ && SemaCheckStringLiteral(C->getRHS(), TheCall, HasVAListArg,
+ format_idx, firstDataArg, isPrintf);
}
case Stmt::ImplicitCastExprClass: {
const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E);
return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
- format_idx, firstDataArg);
+ format_idx, firstDataArg, isPrintf);
}
case Stmt::ParenExprClass: {
const ParenExpr *Expr = cast<ParenExpr>(E);
return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
- format_idx, firstDataArg);
+ format_idx, firstDataArg, isPrintf);
}
case Stmt::DeclRefExprClass: {
@@ -985,7 +973,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
if (isConstant) {
if (const Expr *Init = VD->getAnyInitializer())
return SemaCheckStringLiteral(Init, TheCall,
- HasVAListArg, format_idx, firstDataArg);
+ HasVAListArg, format_idx, firstDataArg,
+ isPrintf);
}
// For vprintf* functions (i.e., HasVAListArg==true), we add a
@@ -1025,7 +1014,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
const Expr *Arg = CE->getArg(ArgIndex - 1);
return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg,
- format_idx, firstDataArg);
+ format_idx, firstDataArg, isPrintf);
}
}
}
@@ -1043,8 +1032,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
StrE = cast<StringLiteral>(E);
if (StrE) {
- CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx,
- firstDataArg);
+ CheckFormatString(StrE, E, TheCall, HasVAListArg, format_idx,
+ firstDataArg, isPrintf);
return true;
}
@@ -1059,7 +1048,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
void
Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
const CallExpr *TheCall) {
- for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+ for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+ e = NonNull->args_end();
i != e; ++i) {
const Expr *ArgExpr = TheCall->getArg(*i);
if (ArgExpr->isNullPointerConstant(Context,
@@ -1069,55 +1059,13 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
}
}
-/// CheckPrintfArguments - Check calls to printf (and similar functions) for
-/// correct use of format strings.
-///
-/// HasVAListArg - A predicate indicating whether the printf-like
-/// function is passed an explicit va_arg argument (e.g., vprintf)
-///
-/// format_idx - The index into Args for the format string.
-///
-/// Improper format strings to functions in the printf family can be
-/// the source of bizarre bugs and very serious security holes. A
-/// good source of information is available in the following paper
-/// (which includes additional references):
-///
-/// FormatGuard: Automatic Protection From printf Format String
-/// Vulnerabilities, Proceedings of the 10th USENIX Security Symposium, 2001.
-///
-/// TODO:
-/// Functionality implemented:
-///
-/// We can statically check the following properties for string
-/// literal format strings for non v.*printf functions (where the
-/// arguments are passed directly):
-//
-/// (1) Are the number of format conversions equal to the number of
-/// data arguments?
-///
-/// (2) Does each format conversion correctly match the type of the
-/// corresponding data argument?
-///
-/// Moreover, for all printf functions we can:
-///
-/// (3) Check for a missing format string (when not caught by type checking).
-///
-/// (4) Check for no-operation flags; e.g. using "#" with format
-/// conversion 'c' (TODO)
-///
-/// (5) Check the use of '%n', a major source of security holes.
-///
-/// (6) Check for malformed format conversions that don't specify anything.
-///
-/// (7) Check for empty format strings. e.g: printf("");
-///
-/// (8) Check that the format string is a wide literal.
-///
-/// All of these checks can be done by parsing the format string.
-///
+/// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar
+/// functions) for correct use of format strings.
void
-Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg) {
+Sema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
+ unsigned format_idx, unsigned firstDataArg,
+ bool isPrintf) {
+
const Expr *Fn = TheCall->getCallee();
// The way the format attribute works in GCC, the implicit this argument
@@ -1132,9 +1080,9 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
--firstDataArg;
}
- // CHECK: printf-like function is called with no format string.
+ // CHECK: printf/scanf-like function is called with no format string.
if (format_idx >= TheCall->getNumArgs()) {
- Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string)
+ Diag(TheCall->getRParenLoc(), diag::warn_missing_format_string)
<< Fn->getSourceRange();
return;
}
@@ -1154,23 +1102,24 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
// ObjC string uses the same format specifiers as C string, so we can use
// the same format string checking logic for both ObjC and C strings.
if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx,
- firstDataArg))
+ firstDataArg, isPrintf))
return; // Literal format string found, check done!
// If there are no arguments specified, warn with -Wformat-security, otherwise
// warn only with -Wformat-nonliteral.
if (TheCall->getNumArgs() == format_idx+1)
Diag(TheCall->getArg(format_idx)->getLocStart(),
- diag::warn_printf_nonliteral_noargs)
+ diag::warn_format_nonliteral_noargs)
<< OrigFormatExpr->getSourceRange();
else
Diag(TheCall->getArg(format_idx)->getLocStart(),
- diag::warn_printf_nonliteral)
+ diag::warn_format_nonliteral)
<< OrigFormatExpr->getSourceRange();
}
namespace {
-class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
+class CheckFormatHandler : public analyze_format_string::FormatStringHandler {
+protected:
Sema &S;
const StringLiteral *FExpr;
const Expr *OrigFormatExpr;
@@ -1185,7 +1134,7 @@ class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
bool usesPositionalArgs;
bool atFirstArg;
public:
- CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+ CheckFormatHandler(Sema &s, const StringLiteral *fexpr,
const Expr *origFormatExpr, unsigned firstDataArg,
unsigned numDataArgs, bool isObjCLiteral,
const char *beg, bool hasVAListArg,
@@ -1203,55 +1152,43 @@ public:
void DoneProcessing();
- void HandleIncompleteFormatSpecifier(const char *startSpecifier,
- unsigned specifierLen);
-
- bool
- HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen);
-
+ void HandleIncompleteSpecifier(const char *startSpecifier,
+ unsigned specifierLen);
+
virtual void HandleInvalidPosition(const char *startSpecifier,
unsigned specifierLen,
- analyze_printf::PositionContext p);
+ analyze_format_string::PositionContext p);
virtual void HandleZeroPosition(const char *startPos, unsigned posLen);
void HandleNullChar(const char *nullCharacter);
- bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen);
-private:
+protected:
+ bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc,
+ const char *startSpec,
+ unsigned specifierLen,
+ const char *csStart, unsigned csLen);
+
SourceRange getFormatStringRange();
- CharSourceRange getFormatSpecifierRange(const char *startSpecifier,
- unsigned specifierLen);
+ CharSourceRange getSpecifierRange(const char *startSpecifier,
+ unsigned specifierLen);
SourceLocation getLocationOfByte(const char *x);
- bool HandleAmount(const analyze_printf::OptionalAmount &Amt, unsigned k,
- const char *startSpecifier, unsigned specifierLen);
- void HandleInvalidAmount(const analyze_printf::FormatSpecifier &FS,
- const analyze_printf::OptionalAmount &Amt,
- unsigned type,
- const char *startSpecifier, unsigned specifierLen);
- void HandleFlag(const analyze_printf::FormatSpecifier &FS,
- const analyze_printf::OptionalFlag &flag,
- const char *startSpecifier, unsigned specifierLen);
- void HandleIgnoredFlag(const analyze_printf::FormatSpecifier &FS,
- const analyze_printf::OptionalFlag &ignoredFlag,
- const analyze_printf::OptionalFlag &flag,
- const char *startSpecifier, unsigned specifierLen);
-
const Expr *getDataArg(unsigned i) const;
+
+ bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS,
+ const analyze_format_string::ConversionSpecifier &CS,
+ const char *startSpecifier, unsigned specifierLen,
+ unsigned argIndex);
};
}
-SourceRange CheckPrintfHandler::getFormatStringRange() {
+SourceRange CheckFormatHandler::getFormatStringRange() {
return OrigFormatExpr->getSourceRange();
}
-CharSourceRange CheckPrintfHandler::
-getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
+CharSourceRange CheckFormatHandler::
+getSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
SourceLocation Start = getLocationOfByte(startSpecifier);
SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
@@ -1261,39 +1198,67 @@ getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
return CharSourceRange::getCharRange(Start, End);
}
-SourceLocation CheckPrintfHandler::getLocationOfByte(const char *x) {
+SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) {
return S.getLocationOfStringLiteralByte(FExpr, x - Beg);
}
-void CheckPrintfHandler::
-HandleIncompleteFormatSpecifier(const char *startSpecifier,
- unsigned specifierLen) {
+void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier,
+ unsigned specifierLen){
SourceLocation Loc = getLocationOfByte(startSpecifier);
S.Diag(Loc, diag::warn_printf_incomplete_specifier)
- << getFormatSpecifierRange(startSpecifier, specifierLen);
+ << getSpecifierRange(startSpecifier, specifierLen);
}
void
-CheckPrintfHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
- analyze_printf::PositionContext p) {
+CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
+ analyze_format_string::PositionContext p) {
SourceLocation Loc = getLocationOfByte(startPos);
- S.Diag(Loc, diag::warn_printf_invalid_positional_specifier)
- << (unsigned) p << getFormatSpecifierRange(startPos, posLen);
+ S.Diag(Loc, diag::warn_format_invalid_positional_specifier)
+ << (unsigned) p << getSpecifierRange(startPos, posLen);
}
-void CheckPrintfHandler::HandleZeroPosition(const char *startPos,
+void CheckFormatHandler::HandleZeroPosition(const char *startPos,
unsigned posLen) {
SourceLocation Loc = getLocationOfByte(startPos);
- S.Diag(Loc, diag::warn_printf_zero_positional_specifier)
- << getFormatSpecifierRange(startPos, posLen);
+ S.Diag(Loc, diag::warn_format_zero_positional_specifier)
+ << getSpecifierRange(startPos, posLen);
+}
+
+void CheckFormatHandler::HandleNullChar(const char *nullCharacter) {
+ // The presence of a null character is likely an error.
+ S.Diag(getLocationOfByte(nullCharacter),
+ diag::warn_printf_format_string_contains_null_char)
+ << getFormatStringRange();
}
-bool CheckPrintfHandler::
-HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
+const Expr *CheckFormatHandler::getDataArg(unsigned i) const {
+ return TheCall->getArg(FirstDataArg + i);
+}
- unsigned argIndex = FS.getArgIndex();
+void CheckFormatHandler::DoneProcessing() {
+ // Does the number of data arguments exceed the number of
+ // format conversions in the format string?
+ if (!HasVAListArg) {
+ // Find any arguments that weren't covered.
+ CoveredArgs.flip();
+ signed notCoveredArg = CoveredArgs.find_first();
+ if (notCoveredArg >= 0) {
+ assert((unsigned)notCoveredArg < NumDataArgs);
+ S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(),
+ diag::warn_printf_data_arg_not_used)
+ << getFormatStringRange();
+ }
+ }
+}
+
+bool
+CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex,
+ SourceLocation Loc,
+ const char *startSpec,
+ unsigned specifierLen,
+ const char *csStart,
+ unsigned csLen) {
+
bool keepGoing = true;
if (argIndex < NumDataArgs) {
// Consider the argument coverered, even though the specifier doesn't
@@ -1308,32 +1273,95 @@ HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
// gibberish when trying to match arguments.
keepGoing = false;
}
+
+ S.Diag(Loc, diag::warn_format_invalid_conversion)
+ << llvm::StringRef(csStart, csLen)
+ << getSpecifierRange(startSpec, specifierLen);
+
+ return keepGoing;
+}
- const analyze_printf::ConversionSpecifier &CS =
- FS.getConversionSpecifier();
- SourceLocation Loc = getLocationOfByte(CS.getStart());
- S.Diag(Loc, diag::warn_printf_invalid_conversion)
- << llvm::StringRef(CS.getStart(), CS.getLength())
- << getFormatSpecifierRange(startSpecifier, specifierLen);
+bool
+CheckFormatHandler::CheckNumArgs(
+ const analyze_format_string::FormatSpecifier &FS,
+ const analyze_format_string::ConversionSpecifier &CS,
+ const char *startSpecifier, unsigned specifierLen, unsigned argIndex) {
- return keepGoing;
+ if (argIndex >= NumDataArgs) {
+ if (FS.usesPositionalArg()) {
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_printf_positional_arg_exceeds_data_args)
+ << (argIndex+1) << NumDataArgs
+ << getSpecifierRange(startSpecifier, specifierLen);
+ }
+ else {
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_printf_insufficient_data_args)
+ << getSpecifierRange(startSpecifier, specifierLen);
+ }
+
+ return false;
+ }
+ return true;
}
-void CheckPrintfHandler::HandleNullChar(const char *nullCharacter) {
- // The presence of a null character is likely an error.
- S.Diag(getLocationOfByte(nullCharacter),
- diag::warn_printf_format_string_contains_null_char)
- << getFormatStringRange();
+//===--- CHECK: Printf format string checking ------------------------------===//
+
+namespace {
+class CheckPrintfHandler : public CheckFormatHandler {
+public:
+ CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+ const Expr *origFormatExpr, unsigned firstDataArg,
+ unsigned numDataArgs, bool isObjCLiteral,
+ const char *beg, bool hasVAListArg,
+ const CallExpr *theCall, unsigned formatIdx)
+ : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+ numDataArgs, isObjCLiteral, beg, hasVAListArg,
+ theCall, formatIdx) {}
+
+
+ bool HandleInvalidPrintfConversionSpecifier(
+ const analyze_printf::PrintfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen);
+
+ bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen);
+
+ bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k,
+ const char *startSpecifier, unsigned specifierLen);
+ void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS,
+ const analyze_printf::OptionalAmount &Amt,
+ unsigned type,
+ const char *startSpecifier, unsigned specifierLen);
+ void HandleFlag(const analyze_printf::PrintfSpecifier &FS,
+ const analyze_printf::OptionalFlag &flag,
+ const char *startSpecifier, unsigned specifierLen);
+ void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS,
+ const analyze_printf::OptionalFlag &ignoredFlag,
+ const analyze_printf::OptionalFlag &flag,
+ const char *startSpecifier, unsigned specifierLen);
+};
}
-const Expr *CheckPrintfHandler::getDataArg(unsigned i) const {
- return TheCall->getArg(FirstDataArg + i);
+bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
+ const analyze_printf::PrintfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+ const analyze_printf::PrintfConversionSpecifier &CS =
+ FS.getConversionSpecifier();
+
+ return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+ getLocationOfByte(CS.getStart()),
+ startSpecifier, specifierLen,
+ CS.getStart(), CS.getLength());
}
-bool
-CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
- unsigned k, const char *startSpecifier,
- unsigned specifierLen) {
+bool CheckPrintfHandler::HandleAmount(
+ const analyze_format_string::OptionalAmount &Amt,
+ unsigned k, const char *startSpecifier,
+ unsigned specifierLen) {
if (Amt.hasDataArgument()) {
if (!HasVAListArg) {
@@ -1341,7 +1369,7 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
if (argIndex >= NumDataArgs) {
S.Diag(getLocationOfByte(Amt.getStart()),
diag::warn_printf_asterisk_missing_arg)
- << k << getFormatSpecifierRange(startSpecifier, specifierLen);
+ << k << getSpecifierRange(startSpecifier, specifierLen);
// Don't do any more checking. We will just emit
// spurious errors.
return false;
@@ -1363,7 +1391,7 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
diag::warn_printf_asterisk_wrong_type)
<< k
<< ATR.getRepresentativeType(S.Context) << T
- << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << getSpecifierRange(startSpecifier, specifierLen)
<< Arg->getSourceRange();
// Don't do any more checking. We will just emit
// spurious errors.
@@ -1375,20 +1403,21 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
}
void CheckPrintfHandler::HandleInvalidAmount(
- const analyze_printf::FormatSpecifier &FS,
+ const analyze_printf::PrintfSpecifier &FS,
const analyze_printf::OptionalAmount &Amt,
unsigned type,
const char *startSpecifier,
unsigned specifierLen) {
- const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier();
+ const analyze_printf::PrintfConversionSpecifier &CS =
+ FS.getConversionSpecifier();
switch (Amt.getHowSpecified()) {
case analyze_printf::OptionalAmount::Constant:
S.Diag(getLocationOfByte(Amt.getStart()),
diag::warn_printf_nonsensical_optional_amount)
<< type
<< CS.toString()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << FixItHint::CreateRemoval(getFormatSpecifierRange(Amt.getStart(),
+ << getSpecifierRange(startSpecifier, specifierLen)
+ << FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(),
Amt.getConstantLength()));
break;
@@ -1397,26 +1426,27 @@ void CheckPrintfHandler::HandleInvalidAmount(
diag::warn_printf_nonsensical_optional_amount)
<< type
<< CS.toString()
- << getFormatSpecifierRange(startSpecifier, specifierLen);
+ << getSpecifierRange(startSpecifier, specifierLen);
break;
}
}
-void CheckPrintfHandler::HandleFlag(const analyze_printf::FormatSpecifier &FS,
+void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS,
const analyze_printf::OptionalFlag &flag,
const char *startSpecifier,
unsigned specifierLen) {
// Warn about pointless flag with a fixit removal.
- const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier();
+ const analyze_printf::PrintfConversionSpecifier &CS =
+ FS.getConversionSpecifier();
S.Diag(getLocationOfByte(flag.getPosition()),
diag::warn_printf_nonsensical_flag)
<< flag.toString() << CS.toString()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << FixItHint::CreateRemoval(getFormatSpecifierRange(flag.getPosition(), 1));
+ << getSpecifierRange(startSpecifier, specifierLen)
+ << FixItHint::CreateRemoval(getSpecifierRange(flag.getPosition(), 1));
}
void CheckPrintfHandler::HandleIgnoredFlag(
- const analyze_printf::FormatSpecifier &FS,
+ const analyze_printf::PrintfSpecifier &FS,
const analyze_printf::OptionalFlag &ignoredFlag,
const analyze_printf::OptionalFlag &flag,
const char *startSpecifier,
@@ -1425,30 +1455,33 @@ void CheckPrintfHandler::HandleIgnoredFlag(
S.Diag(getLocationOfByte(ignoredFlag.getPosition()),
diag::warn_printf_ignored_flag)
<< ignoredFlag.toString() << flag.toString()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << FixItHint::CreateRemoval(getFormatSpecifierRange(
+ << getSpecifierRange(startSpecifier, specifierLen)
+ << FixItHint::CreateRemoval(getSpecifierRange(
ignoredFlag.getPosition(), 1));
}
bool
-CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
+CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
&FS,
const char *startSpecifier,
unsigned specifierLen) {
+ using namespace analyze_format_string;
using namespace analyze_printf;
- const ConversionSpecifier &CS = FS.getConversionSpecifier();
+ const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
- if (atFirstArg) {
- atFirstArg = false;
- usesPositionalArgs = FS.usesPositionalArg();
- }
- else if (usesPositionalArgs != FS.usesPositionalArg()) {
- // Cannot mix-and-match positional and non-positional arguments.
- S.Diag(getLocationOfByte(CS.getStart()),
- diag::warn_printf_mix_positional_nonpositional_args)
- << getFormatSpecifierRange(startSpecifier, specifierLen);
- return false;
+ if (FS.consumesDataArgument()) {
+ if (atFirstArg) {
+ atFirstArg = false;
+ usesPositionalArgs = FS.usesPositionalArg();
+ }
+ else if (usesPositionalArgs != FS.usesPositionalArg()) {
+ // Cannot mix-and-match positional and non-positional arguments.
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_format_mix_positional_nonpositional_args)
+ << getSpecifierRange(startSpecifier, specifierLen);
+ return false;
+ }
}
// First check if the field width, precision, and conversion specifier
@@ -1481,7 +1514,8 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
// Check for using an Objective-C specific conversion specifier
// in a non-ObjC literal.
if (!IsObjCLiteral && CS.isObjCArg()) {
- return HandleInvalidConversionSpecifier(FS, startSpecifier, specifierLen);
+ return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
+ specifierLen);
}
// Check for invalid use of field width
@@ -1520,17 +1554,17 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
const LengthModifier &LM = FS.getLengthModifier();
if (!FS.hasValidLengthModifier())
S.Diag(getLocationOfByte(LM.getStart()),
- diag::warn_printf_nonsensical_length)
+ diag::warn_format_nonsensical_length)
<< LM.toString() << CS.toString()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << FixItHint::CreateRemoval(getFormatSpecifierRange(LM.getStart(),
+ << getSpecifierRange(startSpecifier, specifierLen)
+ << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
LM.getLength()));
// Are we using '%n'?
- if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) {
+ if (CS.getKind() == ConversionSpecifier::nArg) {
// Issue a warning about this being a possible security issue.
S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back)
- << getFormatSpecifierRange(startSpecifier, specifierLen);
+ << getSpecifierRange(startSpecifier, specifierLen);
// Continue checking the other format specifiers.
return true;
}
@@ -1539,22 +1573,8 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
if (HasVAListArg)
return true;
- if (argIndex >= NumDataArgs) {
- if (FS.usesPositionalArg()) {
- S.Diag(getLocationOfByte(CS.getStart()),
- diag::warn_printf_positional_arg_exceeds_data_args)
- << (argIndex+1) << NumDataArgs
- << getFormatSpecifierRange(startSpecifier, specifierLen);
- }
- else {
- S.Diag(getLocationOfByte(CS.getStart()),
- diag::warn_printf_insufficient_data_args)
- << getFormatSpecifierRange(startSpecifier, specifierLen);
- }
-
- // Don't do any more checking.
+ if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
return false;
- }
// Now type check the data expression that matches the
// format specifier.
@@ -1570,7 +1590,7 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
return true;
// We may be able to offer a FixItHint if it is a supported type.
- FormatSpecifier fixedFS = FS;
+ PrintfSpecifier fixedFS = FS;
bool success = fixedFS.fixType(Ex->getType());
if (success) {
@@ -1579,20 +1599,23 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
llvm::raw_svector_ostream os(buf);
fixedFS.toString(os);
+ // FIXME: getRepresentativeType() perhaps should return a string
+ // instead of a QualType to better handle when the representative
+ // type is 'wint_t' (which is defined in the system headers).
S.Diag(getLocationOfByte(CS.getStart()),
diag::warn_printf_conversion_argument_type_mismatch)
<< ATR.getRepresentativeType(S.Context) << Ex->getType()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << getSpecifierRange(startSpecifier, specifierLen)
<< Ex->getSourceRange()
<< FixItHint::CreateReplacement(
- getFormatSpecifierRange(startSpecifier, specifierLen),
+ getSpecifierRange(startSpecifier, specifierLen),
os.str());
}
else {
S.Diag(getLocationOfByte(CS.getStart()),
diag::warn_printf_conversion_argument_type_mismatch)
<< ATR.getRepresentativeType(S.Context) << Ex->getType()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << getSpecifierRange(startSpecifier, specifierLen)
<< Ex->getSourceRange();
}
}
@@ -1600,54 +1623,173 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
return true;
}
-void CheckPrintfHandler::DoneProcessing() {
- // Does the number of data arguments exceed the number of
- // format conversions in the format string?
- if (!HasVAListArg) {
- // Find any arguments that weren't covered.
- CoveredArgs.flip();
- signed notCoveredArg = CoveredArgs.find_first();
- if (notCoveredArg >= 0) {
- assert((unsigned)notCoveredArg < NumDataArgs);
- S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(),
- diag::warn_printf_data_arg_not_used)
- << getFormatStringRange();
+//===--- CHECK: Scanf format string checking ------------------------------===//
+
+namespace {
+class CheckScanfHandler : public CheckFormatHandler {
+public:
+ CheckScanfHandler(Sema &s, const StringLiteral *fexpr,
+ const Expr *origFormatExpr, unsigned firstDataArg,
+ unsigned numDataArgs, bool isObjCLiteral,
+ const char *beg, bool hasVAListArg,
+ const CallExpr *theCall, unsigned formatIdx)
+ : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+ numDataArgs, isObjCLiteral, beg, hasVAListArg,
+ theCall, formatIdx) {}
+
+ bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen);
+
+ bool HandleInvalidScanfConversionSpecifier(
+ const analyze_scanf::ScanfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen);
+
+ void HandleIncompleteScanList(const char *start, const char *end);
+};
+}
+
+void CheckScanfHandler::HandleIncompleteScanList(const char *start,
+ const char *end) {
+ S.Diag(getLocationOfByte(end), diag::warn_scanf_scanlist_incomplete)
+ << getSpecifierRange(start, end - start);
+}
+
+bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
+ const analyze_scanf::ScanfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+
+ const analyze_scanf::ScanfConversionSpecifier &CS =
+ FS.getConversionSpecifier();
+
+ return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+ getLocationOfByte(CS.getStart()),
+ startSpecifier, specifierLen,
+ CS.getStart(), CS.getLength());
+}
+
+bool CheckScanfHandler::HandleScanfSpecifier(
+ const analyze_scanf::ScanfSpecifier &FS,
+ const char *startSpecifier,
+ unsigned specifierLen) {
+
+ using namespace analyze_scanf;
+ using namespace analyze_format_string;
+
+ const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
+
+ // Handle case where '%' and '*' don't consume an argument. These shouldn't
+ // be used to decide if we are using positional arguments consistently.
+ if (FS.consumesDataArgument()) {
+ if (atFirstArg) {
+ atFirstArg = false;
+ usesPositionalArgs = FS.usesPositionalArg();
+ }
+ else if (usesPositionalArgs != FS.usesPositionalArg()) {
+ // Cannot mix-and-match positional and non-positional arguments.
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_format_mix_positional_nonpositional_args)
+ << getSpecifierRange(startSpecifier, specifierLen);
+ return false;
+ }
+ }
+
+ // Check if the field with is non-zero.
+ const OptionalAmount &Amt = FS.getFieldWidth();
+ if (Amt.getHowSpecified() == OptionalAmount::Constant) {
+ if (Amt.getConstantAmount() == 0) {
+ const CharSourceRange &R = getSpecifierRange(Amt.getStart(),
+ Amt.getConstantLength());
+ S.Diag(getLocationOfByte(Amt.getStart()),
+ diag::warn_scanf_nonzero_width)
+ << R << FixItHint::CreateRemoval(R);
}
}
+
+ if (!FS.consumesDataArgument()) {
+ // FIXME: Technically specifying a precision or field width here
+ // makes no sense. Worth issuing a warning at some point.
+ return true;
+ }
+
+ // Consume the argument.
+ unsigned argIndex = FS.getArgIndex();
+ if (argIndex < NumDataArgs) {
+ // The check to see if the argIndex is valid will come later.
+ // We set the bit here because we may exit early from this
+ // function if we encounter some other error.
+ CoveredArgs.set(argIndex);
+ }
+
+ // Check the length modifier is valid with the given conversion specifier.
+ const LengthModifier &LM = FS.getLengthModifier();
+ if (!FS.hasValidLengthModifier()) {
+ S.Diag(getLocationOfByte(LM.getStart()),
+ diag::warn_format_nonsensical_length)
+ << LM.toString() << CS.toString()
+ << getSpecifierRange(startSpecifier, specifierLen)
+ << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
+ LM.getLength()));
+ }
+
+ // The remaining checks depend on the data arguments.
+ if (HasVAListArg)
+ return true;
+
+ if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
+ return false;
+
+ // FIXME: Check that the argument type matches the format specifier.
+
+ return true;
}
-void Sema::CheckPrintfString(const StringLiteral *FExpr,
+void Sema::CheckFormatString(const StringLiteral *FExpr,
const Expr *OrigFormatExpr,
const CallExpr *TheCall, bool HasVAListArg,
- unsigned format_idx, unsigned firstDataArg) {
-
+ unsigned format_idx, unsigned firstDataArg,
+ bool isPrintf) {
+
// CHECK: is the format string a wide literal?
if (FExpr->isWide()) {
Diag(FExpr->getLocStart(),
- diag::warn_printf_format_string_is_wide_literal)
+ diag::warn_format_string_is_wide_literal)
<< OrigFormatExpr->getSourceRange();
return;
}
-
+
// Str - The format string. NOTE: this is NOT null-terminated!
- const char *Str = FExpr->getStrData();
-
+ llvm::StringRef StrRef = FExpr->getString();
+ const char *Str = StrRef.data();
+ unsigned StrLen = StrRef.size();
+
// CHECK: empty format string?
- unsigned StrLen = FExpr->getByteLength();
-
if (StrLen == 0) {
- Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string)
+ Diag(FExpr->getLocStart(), diag::warn_empty_format_string)
<< OrigFormatExpr->getSourceRange();
return;
}
-
- CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
- TheCall->getNumArgs() - firstDataArg,
- isa<ObjCStringLiteral>(OrigFormatExpr), Str,
- HasVAListArg, TheCall, format_idx);
-
- if (!analyze_printf::ParseFormatString(H, Str, Str + StrLen))
- H.DoneProcessing();
+
+ if (isPrintf) {
+ CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+ TheCall->getNumArgs() - firstDataArg,
+ isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+ HasVAListArg, TheCall, format_idx);
+
+ if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen))
+ H.DoneProcessing();
+ }
+ else {
+ CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+ TheCall->getNumArgs() - firstDataArg,
+ isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+ HasVAListArg, TheCall, format_idx);
+
+ if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen))
+ H.DoneProcessing();
+ }
}
//===--- CHECK: Return Address of Stack Variable --------------------------===//
@@ -1729,7 +1871,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
// is AddrOf. All others don't make sense as pointers.
UnaryOperator *U = cast<UnaryOperator>(E);
- if (U->getOpcode() == UnaryOperator::AddrOf)
+ if (U->getOpcode() == UO_AddrOf)
return EvalVal(U->getSubExpr());
else
return NULL;
@@ -1739,9 +1881,9 @@ static DeclRefExpr* EvalAddr(Expr *E) {
// Handle pointer arithmetic. All other binary operators are not valid
// in this context.
BinaryOperator *B = cast<BinaryOperator>(E);
- BinaryOperator::Opcode op = B->getOpcode();
+ BinaryOperatorKind op = B->getOpcode();
- if (op != BinaryOperator::Add && op != BinaryOperator::Sub)
+ if (op != BO_Add && op != BO_Sub)
return NULL;
Expr *Base = B->getLHS();
@@ -1814,7 +1956,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
/// EvalVal - This function is complements EvalAddr in the mutual recursion.
/// See the comments for EvalAddr for more details.
static DeclRefExpr* EvalVal(Expr *E) {
-
+do {
// We should only be called for evaluating non-pointer expressions, or
// expressions with a pointer type that are not used as references but instead
// are l-values (e.g., DeclRefExpr with a pointer type).
@@ -1823,6 +1965,15 @@ static DeclRefExpr* EvalVal(Expr *E) {
// viewed AST node. We then recursively traverse the AST by calling
// EvalAddr and EvalVal appropriately.
switch (E->getStmtClass()) {
+ case Stmt::ImplicitCastExprClass: {
+ ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
+ if (IE->getValueKind() == VK_LValue) {
+ E = IE->getSubExpr();
+ continue;
+ }
+ return NULL;
+ }
+
case Stmt::DeclRefExprClass: {
// DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking
// at code that refers to a variable's name. We check if it has local
@@ -1835,9 +1986,11 @@ static DeclRefExpr* EvalVal(Expr *E) {
return NULL;
}
- case Stmt::ParenExprClass:
+ case Stmt::ParenExprClass: {
// Ignore parentheses.
- return EvalVal(cast<ParenExpr>(E)->getSubExpr());
+ E = cast<ParenExpr>(E)->getSubExpr();
+ continue;
+ }
case Stmt::UnaryOperatorClass: {
// The only unary operator that make sense to handle here
@@ -1845,7 +1998,7 @@ static DeclRefExpr* EvalVal(Expr *E) {
// handling all sorts of rvalues passed to a unary operator.
UnaryOperator *U = cast<UnaryOperator>(E);
- if (U->getOpcode() == UnaryOperator::Deref)
+ if (U->getOpcode() == UO_Deref)
return EvalAddr(U->getSubExpr());
return NULL;
@@ -1876,16 +2029,22 @@ static DeclRefExpr* EvalVal(Expr *E) {
MemberExpr *M = cast<MemberExpr>(E);
// Check for indirect access. We only want direct field accesses.
- if (!M->isArrow())
- return EvalVal(M->getBase());
- else
+ if (M->isArrow())
return NULL;
+
+ // Check whether the member type is itself a reference, in which case
+ // we're not going to refer to the member, but to what the member refers to.
+ if (M->getMemberDecl()->getType()->isReferenceType())
+ return NULL;
+
+ return EvalVal(M->getBase());
}
// Everything else: we simply don't reason about them.
default:
return NULL;
}
+} while (true);
}
//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
@@ -1954,7 +2113,6 @@ struct IntRange {
/// True if the int is known not to have negative values.
bool NonNegative;
- IntRange() {}
IntRange(unsigned Width, bool NonNegative)
: Width(Width), NonNegative(NonNegative)
{}
@@ -2063,13 +2221,13 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
// user has an explicit widening cast, we should treat the value as
// being of the new, wider type.
if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) {
- if (CE->getCastKind() == CastExpr::CK_NoOp)
+ if (CE->getCastKind() == CK_NoOp)
return GetExprRange(C, CE->getSubExpr(), MaxWidth);
IntRange OutputTypeRange = IntRange::forType(C, CE->getType());
- bool isIntegerCast = (CE->getCastKind() == CastExpr::CK_IntegralCast);
- if (!isIntegerCast && CE->getCastKind() == CastExpr::CK_Unknown)
+ bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
+ if (!isIntegerCast && CE->getCastKind() == CK_Unknown)
isIntegerCast = CE->getSubExpr()->getType()->isIntegerType();
// Assume that non-integer casts can span the full range of the type.
@@ -2108,38 +2266,38 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
switch (BO->getOpcode()) {
// Boolean-valued operations are single-bit and positive.
- case BinaryOperator::LAnd:
- case BinaryOperator::LOr:
- case BinaryOperator::LT:
- case BinaryOperator::GT:
- case BinaryOperator::LE:
- case BinaryOperator::GE:
- case BinaryOperator::EQ:
- case BinaryOperator::NE:
+ case BO_LAnd:
+ case BO_LOr:
+ case BO_LT:
+ case BO_GT:
+ case BO_LE:
+ case BO_GE:
+ case BO_EQ:
+ case BO_NE:
return IntRange::forBoolType();
// The type of these compound assignments is the type of the LHS,
// so the RHS is not necessarily an integer.
- case BinaryOperator::MulAssign:
- case BinaryOperator::DivAssign:
- case BinaryOperator::RemAssign:
- case BinaryOperator::AddAssign:
- case BinaryOperator::SubAssign:
+ case BO_MulAssign:
+ case BO_DivAssign:
+ case BO_RemAssign:
+ case BO_AddAssign:
+ case BO_SubAssign:
return IntRange::forType(C, E->getType());
// Operations with opaque sources are black-listed.
- case BinaryOperator::PtrMemD:
- case BinaryOperator::PtrMemI:
+ case BO_PtrMemD:
+ case BO_PtrMemI:
return IntRange::forType(C, E->getType());
// Bitwise-and uses the *infinum* of the two source ranges.
- case BinaryOperator::And:
- case BinaryOperator::AndAssign:
+ case BO_And:
+ case BO_AndAssign:
return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth),
GetExprRange(C, BO->getRHS(), MaxWidth));
// Left shift gets black-listed based on a judgement call.
- case BinaryOperator::Shl:
+ case BO_Shl:
// ...except that we want to treat '1 << (blah)' as logically
// positive. It's an important idiom.
if (IntegerLiteral *I
@@ -2151,12 +2309,12 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
}
// fallthrough
- case BinaryOperator::ShlAssign:
+ case BO_ShlAssign:
return IntRange::forType(C, E->getType());
// Right shift by a constant can narrow its left argument.
- case BinaryOperator::Shr:
- case BinaryOperator::ShrAssign: {
+ case BO_Shr:
+ case BO_ShrAssign: {
IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);
// If the shift amount is a positive constant, drop the width by
@@ -2175,11 +2333,11 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
}
// Comma acts as its right operand.
- case BinaryOperator::Comma:
+ case BO_Comma:
return GetExprRange(C, BO->getRHS(), MaxWidth);
// Black-list pointer subtractions.
- case BinaryOperator::Sub:
+ case BO_Sub:
if (BO->getLHS()->getType()->isPointerType())
return IntRange::forType(C, E->getType());
// fallthrough
@@ -2198,13 +2356,12 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
switch (UO->getOpcode()) {
// Boolean-valued operations are white-listed.
- case UnaryOperator::LNot:
+ case UO_LNot:
return IntRange::forBoolType();
// Operations with opaque sources are black-listed.
- case UnaryOperator::Deref:
- case UnaryOperator::AddrOf: // should be impossible
- case UnaryOperator::OffsetOf:
+ case UO_Deref:
+ case UO_AddrOf: // should be impossible
return IntRange::forType(C, E->getType());
default:
@@ -2277,20 +2434,20 @@ bool IsZero(Sema &S, Expr *E) {
}
void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
- BinaryOperator::Opcode op = E->getOpcode();
- if (op == BinaryOperator::LT && IsZero(S, E->getRHS())) {
+ BinaryOperatorKind op = E->getOpcode();
+ if (op == BO_LT && IsZero(S, E->getRHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
<< "< 0" << "false"
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
- } else if (op == BinaryOperator::GE && IsZero(S, E->getRHS())) {
+ } else if (op == BO_GE && IsZero(S, E->getRHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
<< ">= 0" << "true"
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
- } else if (op == BinaryOperator::GT && IsZero(S, E->getLHS())) {
+ } else if (op == BO_GT && IsZero(S, E->getLHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
<< "0 >" << "false"
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
- } else if (op == BinaryOperator::LE && IsZero(S, E->getLHS())) {
+ } else if (op == BO_LE && IsZero(S, E->getLHS())) {
S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
<< "0 <=" << "true"
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
@@ -2319,7 +2476,7 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
// We don't do anything special if this isn't an unsigned integral
// comparison: we're only interested in integral comparisons, and
// signed comparisons only happen in cases we don't care to warn about.
- if (!T->isUnsignedIntegerType())
+ if (!T->hasUnsignedIntegerRepresentation())
return AnalyzeImpConvsInComparison(S, E);
Expr *lex = E->getLHS()->IgnoreParenImpCasts();
@@ -2328,12 +2485,12 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
// Check to see if one of the (unmodified) operands is of different
// signedness.
Expr *signedOperand, *unsignedOperand;
- if (lex->getType()->isSignedIntegerType()) {
- assert(!rex->getType()->isSignedIntegerType() &&
+ if (lex->getType()->hasSignedIntegerRepresentation()) {
+ assert(!rex->getType()->hasSignedIntegerRepresentation() &&
"unsigned comparison between two signed integer expressions?");
signedOperand = lex;
unsignedOperand = rex;
- } else if (rex->getType()->isSignedIntegerType()) {
+ } else if (rex->getType()->hasSignedIntegerRepresentation()) {
signedOperand = rex;
unsignedOperand = lex;
} else {
@@ -2648,3 +2805,48 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
return HasInvalidParm;
}
+
+/// CheckCastAlign - Implements -Wcast-align, which warns when a
+/// pointer cast increases the alignment requirements.
+void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
+ // This is actually a lot of work to potentially be doing on every
+ // cast; don't do it if we're ignoring -Wcast_align (as is the default).
+ if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align)
+ == Diagnostic::Ignored)
+ return;
+
+ // Ignore dependent types.
+ if (T->isDependentType() || Op->getType()->isDependentType())
+ return;
+
+ // Require that the destination be a pointer type.
+ const PointerType *DestPtr = T->getAs<PointerType>();
+ if (!DestPtr) return;
+
+ // If the destination has alignment 1, we're done.
+ QualType DestPointee = DestPtr->getPointeeType();
+ if (DestPointee->isIncompleteType()) return;
+ CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee);
+ if (DestAlign.isOne()) return;
+
+ // Require that the source be a pointer type.
+ const PointerType *SrcPtr = Op->getType()->getAs<PointerType>();
+ if (!SrcPtr) return;
+ QualType SrcPointee = SrcPtr->getPointeeType();
+
+ // Whitelist casts from cv void*. We already implicitly
+ // whitelisted casts to cv void*, since they have alignment 1.
+ // Also whitelist casts involving incomplete types, which implicitly
+ // includes 'void'.
+ if (SrcPointee->isIncompleteType()) return;
+
+ CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee);
+ if (SrcAlign >= DestAlign) return;
+
+ Diag(TRange.getBegin(), diag::warn_cast_align)
+ << Op->getType() << T
+ << static_cast<unsigned>(SrcAlign.getQuantity())
+ << static_cast<unsigned>(DestAlign.getQuantity())
+ << TRange << Op->getSourceRange();
+}
+
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 55288750fd5f..f00d1cd20f1e 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -10,10 +10,14 @@
// This file defines the code-completion semantic actions.
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Lex/MacroInfo.h"
@@ -21,11 +25,13 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
#include <list>
#include <map>
#include <vector>
using namespace clang;
+using namespace sema;
namespace {
/// \brief A container of code-completion results.
@@ -37,7 +43,7 @@ namespace {
/// filtered out (returns false).
typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
private:
/// \brief The actual results we have found.
@@ -130,17 +136,28 @@ namespace {
/// different levels of, e.g., the inheritance hierarchy.
std::list<ShadowMap> ShadowMaps;
+ /// \brief If we're potentially referring to a C++ member function, the set
+ /// of qualifiers applied to the object type.
+ Qualifiers ObjectTypeQualifiers;
+
+ /// \brief Whether the \p ObjectTypeQualifiers field is active.
+ bool HasObjectTypeQualifiers;
+
+ /// \brief The selector that we prefer.
+ Selector PreferredSelector;
+
void AdjustResultPriorityForPreferredType(Result &R);
public:
explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
- : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
+ : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
+ HasObjectTypeQualifiers(false) { }
/// \brief Whether we should include code patterns in the completion
/// results.
bool includeCodePatterns() const {
return SemaRef.CodeCompleter &&
- SemaRef.CodeCompleter->includeCodePatterns();
+ SemaRef.CodeCompleter->includeCodePatterns();
}
/// \brief Set the filter used for code-completion results.
@@ -161,6 +178,27 @@ namespace {
PreferredType = SemaRef.Context.getCanonicalType(T);
}
+ /// \brief Set the cv-qualifiers on the object type, for us in filtering
+ /// calls to member functions.
+ ///
+ /// When there are qualifiers in this set, they will be used to filter
+ /// out member functions that aren't available (because there will be a
+ /// cv-qualifier mismatch) or prefer functions with an exact qualifier
+ /// match.
+ void setObjectTypeQualifiers(Qualifiers Quals) {
+ ObjectTypeQualifiers = Quals;
+ HasObjectTypeQualifiers = true;
+ }
+
+ /// \brief Set the preferred selector.
+ ///
+ /// When an Objective-C method declaration result is added, and that
+ /// method's selector matches this preferred selector, we give that method
+ /// a slight priority boost.
+ void setPreferredSelector(Selector Sel) {
+ PreferredSelector = Sel;
+ }
+
/// \brief Specify whether nested-name-specifiers are allowed.
void allowNestedNameSpecifiers(bool Allow = true) {
AllowNestedNameSpecifiers = Allow;
@@ -227,6 +265,7 @@ namespace {
//@{
bool IsOrdinaryName(NamedDecl *ND) const;
bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
+ bool IsIntegralConstantValue(NamedDecl *ND) const;
bool IsOrdinaryNonValueName(NamedDecl *ND) const;
bool IsNestedNameSpecifier(NamedDecl *ND) const;
bool IsEnum(NamedDecl *ND) const;
@@ -238,6 +277,7 @@ namespace {
bool IsMember(NamedDecl *ND) const;
bool IsObjCIvar(NamedDecl *ND) const;
bool IsObjCMessageReceiver(NamedDecl *ND) const;
+ bool IsObjCCollection(NamedDecl *ND) const;
//@}
};
}
@@ -365,8 +405,12 @@ getRequiredQualification(ASTContext &Context,
DeclContext *Parent = TargetParents.back();
TargetParents.pop_back();
- if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
+ if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
+ if (!Namespace->getIdentifier())
+ continue;
+
Result = NestedNameSpecifier::Create(Context, Result, Namespace);
+ }
else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
Result = NestedNameSpecifier::Create(Context, Result,
false,
@@ -425,6 +469,12 @@ bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
if (isa<CXXConstructorDecl>(ND))
return false;
+ if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
+ ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
+ Filter != &ResultBuilder::IsNamespace &&
+ Filter != &ResultBuilder::IsNamespaceOrAlias))
+ AsNestedNameSpecifier = true;
+
// Filter out any unwanted results.
if (Filter && !(this->*Filter)(ND)) {
// Check whether it is interesting as a nested-name-specifier.
@@ -438,11 +488,7 @@ bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
}
return false;
- }
-
- if (Filter == &ResultBuilder::IsNestedNameSpecifier)
- AsNestedNameSpecifier = true;
-
+ }
// ... then it must be interesting!
return true;
}
@@ -455,13 +501,13 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
if (!SemaRef.getLangOptions().CPlusPlus)
return true;
- DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
+ DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
// There is no way to qualify a name declared in a function or method.
if (HiddenCtx->isFunctionOrMethod())
return true;
- if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
+ if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
return true;
// We can refer to the result with the appropriate qualification. Do it.
@@ -475,21 +521,9 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
return false;
}
-enum SimplifiedTypeClass {
- STC_Arithmetic,
- STC_Array,
- STC_Block,
- STC_Function,
- STC_ObjectiveC,
- STC_Other,
- STC_Pointer,
- STC_Record,
- STC_Void
-};
-
/// \brief A simplified classification of types used to determine whether two
/// types are "similar enough" when adjusting priorities.
-static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
+SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
switch (T->getTypeClass()) {
case Type::Builtin:
switch (cast<BuiltinType>(T)->getKind()) {
@@ -560,7 +594,7 @@ static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
/// \brief Get the type that a given expression will have if this declaration
/// is used as an expression in its "typical" code-completion form.
-static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
+QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
@@ -594,9 +628,12 @@ void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
CanQualType TC = SemaRef.Context.getCanonicalType(T);
// Check for exactly-matching types (modulo qualifiers).
- if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
- R.Priority /= CCF_ExactTypeMatch;
- // Check for nearly-matching types, based on classification of each.
+ if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
+ if (PreferredType->isVoidType())
+ R.Priority += CCD_VoidMatch;
+ else
+ R.Priority /= CCF_ExactTypeMatch;
+ } // Check for nearly-matching types, based on classification of each.
else if ((getSimplifiedTypeClass(PreferredType)
== getSimplifiedTypeClass(TC)) &&
!(PreferredType->isEnumeralType() && TC->isEnumeralType()))
@@ -681,7 +718,14 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
// Make sure that any given declaration only shows up in the result set once.
if (!AllDeclsFound.insert(CanonDecl))
return;
-
+
+ // If this is an Objective-C method declaration whose selector matches our
+ // preferred selector, give it a priority boost.
+ if (!PreferredSelector.isNull())
+ if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+ if (PreferredSelector == Method->getSelector())
+ R.Priority += CCD_SelectorMatch;
+
// If the filter is for nested-name-specifiers, then this result starts a
// nested-name-specifier.
if (AsNestedNameSpecifier) {
@@ -689,7 +733,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
R.Priority = CCP_NestedNameSpecifier;
} else if (!PreferredType.isNull())
AdjustResultPriorityForPreferredType(R);
-
+
// If this result is supposed to have an informative qualifier, add one.
if (R.QualifierIsInformative && !R.Qualifier &&
!R.StartsNestedNameSpecifier) {
@@ -742,7 +786,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
}
else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
isa<CXXRecordDecl>(R.Declaration->getDeclContext()
- ->getLookupContext()))
+ ->getRedeclContext()))
R.QualifierIsInformative = true;
// If this result is supposed to have an informative qualifier, add one.
@@ -762,9 +806,30 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
if (InBaseClass)
R.Priority += CCD_InBaseClass;
+ // If this is an Objective-C method declaration whose selector matches our
+ // preferred selector, give it a priority boost.
+ if (!PreferredSelector.isNull())
+ if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+ if (PreferredSelector == Method->getSelector())
+ R.Priority += CCD_SelectorMatch;
+
if (!PreferredType.isNull())
AdjustResultPriorityForPreferredType(R);
+ if (HasObjectTypeQualifiers)
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
+ if (Method->isInstance()) {
+ Qualifiers MethodQuals
+ = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
+ if (ObjectTypeQualifiers == MethodQuals)
+ R.Priority += CCD_ObjectQualifierMatch;
+ else if (ObjectTypeQualifiers - MethodQuals) {
+ // The method cannot be invoked, because doing so would drop
+ // qualifiers.
+ return;
+ }
+ }
+
// Insert this result into the set of results.
Results.push_back(R);
}
@@ -821,6 +886,17 @@ bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
return ND->getIdentifierNamespace() & IDNS;
}
+bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
+ if (!IsOrdinaryNonTypeName(ND))
+ return 0;
+
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
+ if (VD->getType()->isIntegralOrEnumerationType())
+ return true;
+
+ return false;
+}
+
/// \brief Determines whether this given declaration will be found by
/// ordinary name lookup.
bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
@@ -888,7 +964,10 @@ bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
/// \brief Determines whether the given declaration is a type.
bool ResultBuilder::IsType(NamedDecl *ND) const {
- return isa<TypeDecl>(ND);
+ if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
+ ND = Using->getTargetDecl();
+
+ return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
}
/// \brief Determines which members of a class should be visible via
@@ -944,6 +1023,20 @@ bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
return isObjCReceiverType(SemaRef.Context, T);
}
+bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
+ if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
+ (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
+ return false;
+
+ QualType T = getDeclUsageType(SemaRef.Context, ND);
+ if (T.isNull())
+ return false;
+
+ T = SemaRef.Context.getBaseElementType(T);
+ return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
+ T->isObjCIdType() ||
+ (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
+}
/// \rief Determines whether the given declaration is an Objective-C
/// instance variable.
@@ -971,7 +1064,7 @@ namespace {
/// \brief Add type specifiers for the current language as keyword results.
static void AddTypeSpecifierResults(const LangOptions &LangOpts,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
Results.AddResult(Result("short", CCP_Type));
Results.AddResult(Result("long", CCP_Type));
Results.AddResult(Result("signed", CCP_Type));
@@ -1046,10 +1139,10 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
}
}
-static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
+static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
const LangOptions &LangOpts,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Note: we don't suggest either "auto" or "register", because both
// are pointless as storage specifiers. Elsewhere, we suggest "auto"
// in C++0x as a type specifier.
@@ -1057,13 +1150,13 @@ static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
Results.AddResult(Result("static"));
}
-static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
+static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
const LangOptions &LangOpts,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
switch (CCC) {
- case Action::CCC_Class:
- case Action::CCC_MemberTemplate:
+ case Sema::PCC_Class:
+ case Sema::PCC_MemberTemplate:
if (LangOpts.CPlusPlus) {
Results.AddResult(Result("explicit"));
Results.AddResult(Result("friend"));
@@ -1072,20 +1165,21 @@ static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
}
// Fall through
- case Action::CCC_ObjCInterface:
- case Action::CCC_ObjCImplementation:
- case Action::CCC_Namespace:
- case Action::CCC_Template:
+ case Sema::PCC_ObjCInterface:
+ case Sema::PCC_ObjCImplementation:
+ case Sema::PCC_Namespace:
+ case Sema::PCC_Template:
if (LangOpts.CPlusPlus || LangOpts.C99)
Results.AddResult(Result("inline"));
break;
- case Action::CCC_ObjCInstanceVariableList:
- case Action::CCC_Expression:
- case Action::CCC_Statement:
- case Action::CCC_ForInit:
- case Action::CCC_Condition:
- case Action::CCC_RecoveryInFunction:
+ case Sema::PCC_ObjCInstanceVariableList:
+ case Sema::PCC_Expression:
+ case Sema::PCC_Statement:
+ case Sema::PCC_ForInit:
+ case Sema::PCC_Condition:
+ case Sema::PCC_RecoveryInFunction:
+ case Sema::PCC_Type:
break;
}
}
@@ -1110,31 +1204,32 @@ static void AddTypedefResult(ResultBuilder &Results) {
Pattern->AddPlaceholderChunk("type");
Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Pattern->AddPlaceholderChunk("name");
- Results.AddResult(CodeCompleteConsumer::Result(Pattern));
+ Results.AddResult(CodeCompletionResult(Pattern));
}
-static bool WantTypesInContext(Action::CodeCompletionContext CCC,
+static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
const LangOptions &LangOpts) {
if (LangOpts.CPlusPlus)
return true;
switch (CCC) {
- case Action::CCC_Namespace:
- case Action::CCC_Class:
- case Action::CCC_ObjCInstanceVariableList:
- case Action::CCC_Template:
- case Action::CCC_MemberTemplate:
- case Action::CCC_Statement:
- case Action::CCC_RecoveryInFunction:
+ case Sema::PCC_Namespace:
+ case Sema::PCC_Class:
+ case Sema::PCC_ObjCInstanceVariableList:
+ case Sema::PCC_Template:
+ case Sema::PCC_MemberTemplate:
+ case Sema::PCC_Statement:
+ case Sema::PCC_RecoveryInFunction:
+ case Sema::PCC_Type:
return true;
- case Action::CCC_ObjCInterface:
- case Action::CCC_ObjCImplementation:
- case Action::CCC_Expression:
- case Action::CCC_Condition:
+ case Sema::PCC_ObjCInterface:
+ case Sema::PCC_ObjCImplementation:
+ case Sema::PCC_Expression:
+ case Sema::PCC_Condition:
return false;
- case Action::CCC_ForInit:
+ case Sema::PCC_ForInit:
return LangOpts.ObjC1 || LangOpts.C99;
}
@@ -1142,13 +1237,13 @@ static bool WantTypesInContext(Action::CodeCompletionContext CCC,
}
/// \brief Add language constructs that show up for "ordinary" names.
-static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
+static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
Scope *S,
Sema &SemaRef,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
switch (CCC) {
- case Action::CCC_Namespace:
+ case Sema::PCC_Namespace:
if (SemaRef.getLangOptions().CPlusPlus) {
CodeCompletionString *Pattern = 0;
@@ -1207,7 +1302,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
AddTypedefResult(Results);
// Fall through
- case Action::CCC_Class:
+ case Sema::PCC_Class:
if (SemaRef.getLangOptions().CPlusPlus) {
// Using declaration
CodeCompletionString *Pattern = new CodeCompletionString;
@@ -1231,7 +1326,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
Results.AddResult(Result(Pattern));
}
- if (CCC == Action::CCC_Class) {
+ if (CCC == Sema::PCC_Class) {
AddTypedefResult(Results);
// public:
@@ -1255,8 +1350,8 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
}
// Fall through
- case Action::CCC_Template:
- case Action::CCC_MemberTemplate:
+ case Sema::PCC_Template:
+ case Sema::PCC_MemberTemplate:
if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
// template < parameters >
CodeCompletionString *Pattern = new CodeCompletionString;
@@ -1271,24 +1366,24 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
break;
- case Action::CCC_ObjCInterface:
+ case Sema::PCC_ObjCInterface:
AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
break;
- case Action::CCC_ObjCImplementation:
+ case Sema::PCC_ObjCImplementation:
AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
break;
- case Action::CCC_ObjCInstanceVariableList:
+ case Sema::PCC_ObjCInstanceVariableList:
AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
break;
- case Action::CCC_RecoveryInFunction:
- case Action::CCC_Statement: {
+ case Sema::PCC_RecoveryInFunction:
+ case Sema::PCC_Statement: {
AddTypedefResult(Results);
CodeCompletionString *Pattern = 0;
@@ -1344,7 +1439,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
}
// Switch-specific statements.
- if (!SemaRef.getSwitchStack().empty()) {
+ if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
// case expression:
Pattern = new CodeCompletionString;
Pattern->AddTypedTextChunk("case");
@@ -1460,12 +1555,12 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
}
// Fall through (for statement expressions).
- case Action::CCC_ForInit:
- case Action::CCC_Condition:
+ case Sema::PCC_ForInit:
+ case Sema::PCC_Condition:
AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
// Fall through: conditions and statements can have expressions.
- case Action::CCC_Expression: {
+ case Sema::PCC_Expression: {
CodeCompletionString *Pattern = 0;
if (SemaRef.getLangOptions().CPlusPlus) {
// 'this', if we're in a non-static member function.
@@ -1600,12 +1695,15 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
Results.AddResult(Result(Pattern));
break;
}
+
+ case Sema::PCC_Type:
+ break;
}
if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
Results.AddResult(Result("operator"));
}
@@ -1645,6 +1743,117 @@ static void AddResultTypeChunk(ASTContext &Context,
Result->AddResultTypeChunk(TypeStr);
}
+static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
+ CodeCompletionString *Result) {
+ if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
+ if (Sentinel->getSentinel() == 0) {
+ if (Context.getLangOptions().ObjC1 &&
+ Context.Idents.get("nil").hasMacroDefinition())
+ Result->AddTextChunk(", nil");
+ else if (Context.Idents.get("NULL").hasMacroDefinition())
+ Result->AddTextChunk(", NULL");
+ else
+ Result->AddTextChunk(", (void*)0");
+ }
+}
+
+static std::string FormatFunctionParameter(ASTContext &Context,
+ ParmVarDecl *Param,
+ bool SuppressName = false) {
+ bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
+ if (Param->getType()->isDependentType() ||
+ !Param->getType()->isBlockPointerType()) {
+ // The argument for a dependent or non-block parameter is a placeholder
+ // containing that parameter's type.
+ std::string Result;
+
+ if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
+ Result = Param->getIdentifier()->getName();
+
+ Param->getType().getAsStringInternal(Result,
+ Context.PrintingPolicy);
+
+ if (ObjCMethodParam) {
+ Result = "(" + Result;
+ Result += ")";
+ if (Param->getIdentifier() && !SuppressName)
+ Result += Param->getIdentifier()->getName();
+ }
+ return Result;
+ }
+
+ // The argument for a block pointer parameter is a block literal with
+ // the appropriate type.
+ FunctionProtoTypeLoc *Block = 0;
+ TypeLoc TL;
+ if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
+ TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+ while (true) {
+ // Look through typedefs.
+ if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
+ if (TypeSourceInfo *InnerTSInfo
+ = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
+ TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ }
+
+ // Look through qualified types
+ if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
+ TL = QualifiedTL->getUnqualifiedLoc();
+ continue;
+ }
+
+ // Try to get the function prototype behind the block pointer type,
+ // then we're done.
+ if (BlockPointerTypeLoc *BlockPtr
+ = dyn_cast<BlockPointerTypeLoc>(&TL)) {
+ TL = BlockPtr->getPointeeLoc();
+ Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
+ }
+ break;
+ }
+ }
+
+ if (!Block) {
+ // We were unable to find a FunctionProtoTypeLoc with parameter names
+ // for the block; just use the parameter type as a placeholder.
+ std::string Result;
+ Param->getType().getUnqualifiedType().
+ getAsStringInternal(Result, Context.PrintingPolicy);
+
+ if (ObjCMethodParam) {
+ Result = "(" + Result;
+ Result += ")";
+ if (Param->getIdentifier())
+ Result += Param->getIdentifier()->getName();
+ }
+
+ return Result;
+ }
+
+ // We have the function prototype behind the block pointer type, as it was
+ // written in the source.
+ std::string Result = "(^)(";
+ for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
+ if (I)
+ Result += ", ";
+ Result += FormatFunctionParameter(Context, Block->getArg(I));
+
+ if (I == N - 1 && Block->getTypePtr()->isVariadic())
+ Result += ", ...";
+ }
+ if (Block->getTypePtr()->isVariadic() && Block->getNumArgs() == 0)
+ Result += "...";
+ else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
+ Result += "void";
+
+ Result += ")";
+ Block->getTypePtr()->getResultType().getAsStringInternal(Result,
+ Context.PrintingPolicy);
+ return Result;
+}
+
/// \brief Add function parameter chunks to the given code completion string.
static void AddFunctionParameterChunks(ASTContext &Context,
FunctionDecl *Function,
@@ -1668,21 +1877,23 @@ static void AddFunctionParameterChunks(ASTContext &Context,
CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
// Format the placeholder string.
- std::string PlaceholderStr;
- if (Param->getIdentifier())
- PlaceholderStr = Param->getIdentifier()->getName();
-
- Param->getType().getAsStringInternal(PlaceholderStr,
- Context.PrintingPolicy);
-
+ std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
+
+ if (Function->isVariadic() && P == N - 1)
+ PlaceholderStr += ", ...";
+
// Add the placeholder string.
CCStr->AddPlaceholderChunk(PlaceholderStr);
}
if (const FunctionProtoType *Proto
= Function->getType()->getAs<FunctionProtoType>())
- if (Proto->isVariadic())
- CCStr->AddPlaceholderChunk(", ...");
+ if (Proto->isVariadic()) {
+ if (Proto->getNumArgs() == 0)
+ CCStr->AddPlaceholderChunk("...");
+
+ MaybeAddSentinel(Context, Function, CCStr);
+ }
}
/// \brief Add template parameter chunks to the given code completion string.
@@ -1799,13 +2010,15 @@ static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
/// how to use this result, or NULL to indicate that the string or name of the
/// result is all that is needed.
CodeCompletionString *
-CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
+CodeCompletionResult::CreateCodeCompletionString(Sema &S,
+ CodeCompletionString *Result) {
typedef CodeCompletionString::Chunk Chunk;
if (Kind == RK_Pattern)
- return Pattern->Clone();
+ return Pattern->Clone(Result);
- CodeCompletionString *Result = new CodeCompletionString;
+ if (!Result)
+ Result = new CodeCompletionString;
if (Kind == RK_Keyword) {
Result->AddTypedTextChunk(Keyword);
@@ -1978,10 +2191,20 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
continue;
std::string Arg;
- (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
- Arg = "(" + Arg + ")";
- if (IdentifierInfo *II = (*P)->getIdentifier())
- Arg += II->getName().str();
+
+ if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
+ Arg = FormatFunctionParameter(S.Context, *P, true);
+ else {
+ (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
+ Arg = "(" + Arg + ")";
+ if (IdentifierInfo *II = (*P)->getIdentifier())
+ if (DeclaringEntity || AllParametersAreInformative)
+ Arg += II->getName().str();
+ }
+
+ if (Method->isVariadic() && (P + 1) == PEnd)
+ Arg += ", ...";
+
if (DeclaringEntity)
Result->AddTextChunk(Arg);
else if (AllParametersAreInformative)
@@ -1991,12 +2214,16 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
}
if (Method->isVariadic()) {
- if (DeclaringEntity)
- Result->AddTextChunk(", ...");
- else if (AllParametersAreInformative)
- Result->AddInformativeChunk(", ...");
- else
- Result->AddPlaceholderChunk(", ...");
+ if (Method->param_size() == 0) {
+ if (DeclaringEntity)
+ Result->AddTextChunk(", ...");
+ else if (AllParametersAreInformative)
+ Result->AddInformativeChunk(", ...");
+ else
+ Result->AddPlaceholderChunk(", ...");
+ }
+
+ MaybeAddSentinel(S.Context, Method, Result);
}
return Result;
@@ -2076,226 +2303,421 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
return Result;
}
-namespace {
- struct SortCodeCompleteResult {
- typedef CodeCompleteConsumer::Result Result;
-
- bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
- Selector XSel = X.getObjCSelector();
- Selector YSel = Y.getObjCSelector();
- if (!XSel.isNull() && !YSel.isNull()) {
- // We are comparing two selectors.
- unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
- if (N == 0)
- ++N;
- for (unsigned I = 0; I != N; ++I) {
- IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
- IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
- if (!XId || !YId)
- return XId && !YId;
-
- switch (XId->getName().compare_lower(YId->getName())) {
- case -1: return true;
- case 1: return false;
- default: break;
- }
- }
-
- return XSel.getNumArgs() < YSel.getNumArgs();
- }
+unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
+ bool PreferredTypeIsPointer) {
+ unsigned Priority = CCP_Macro;
+
+ // Treat the "nil" and "NULL" macros as null pointer constants.
+ if (MacroName.equals("nil") || MacroName.equals("NULL")) {
+ Priority = CCP_Constant;
+ if (PreferredTypeIsPointer)
+ Priority = Priority / CCF_SimilarTypeMatch;
+ }
+
+ return Priority;
+}
- // For non-selectors, order by kind.
- if (X.getNameKind() != Y.getNameKind())
- return X.getNameKind() < Y.getNameKind();
-
- // Order identifiers by comparison of their lowercased names.
- if (IdentifierInfo *XId = X.getAsIdentifierInfo())
- return XId->getName().compare_lower(
- Y.getAsIdentifierInfo()->getName()) < 0;
-
- // Order overloaded operators by the order in which they appear
- // in our list of operators.
- if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
- return XOp < Y.getCXXOverloadedOperator();
-
- // Order C++0x user-defined literal operators lexically by their
- // lowercased suffixes.
- if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
- return XLit->getName().compare_lower(
- Y.getCXXLiteralIdentifier()->getName()) < 0;
-
- // The only stable ordering we have is to turn the name into a
- // string and then compare the lower-case strings. This is
- // inefficient, but thankfully does not happen too often.
- return llvm::StringRef(X.getAsString()).compare_lower(
- Y.getAsString()) < 0;
- }
-
- /// \brief Retrieve the name that should be used to order a result.
- ///
- /// If the name needs to be constructed as a string, that string will be
- /// saved into Saved and the returned StringRef will refer to it.
- static llvm::StringRef getOrderedName(const Result &R,
- std::string &Saved) {
- switch (R.Kind) {
- case Result::RK_Keyword:
- return R.Keyword;
-
- case Result::RK_Pattern:
- return R.Pattern->getTypedText();
-
- case Result::RK_Macro:
- return R.Macro->getName();
-
- case Result::RK_Declaration:
- // Handle declarations below.
- break;
- }
-
- DeclarationName Name = R.Declaration->getDeclName();
-
- // If the name is a simple identifier (by far the common case), or a
- // zero-argument selector, just return a reference to that identifier.
- if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
- return Id->getName();
- if (Name.isObjCZeroArgSelector())
- if (IdentifierInfo *Id
- = Name.getObjCSelector().getIdentifierInfoForSlot(0))
- return Id->getName();
-
- Saved = Name.getAsString();
- return Saved;
- }
-
- bool operator()(const Result &X, const Result &Y) const {
- std::string XSaved, YSaved;
- llvm::StringRef XStr = getOrderedName(X, XSaved);
- llvm::StringRef YStr = getOrderedName(Y, YSaved);
- int cmp = XStr.compare_lower(YStr);
- if (cmp)
- return cmp < 0;
-
- // Non-hidden names precede hidden names.
- if (X.Hidden != Y.Hidden)
- return !X.Hidden;
+CXCursorKind clang::getCursorKindForDecl(Decl *D) {
+ if (!D)
+ return CXCursor_UnexposedDecl;
+
+ switch (D->getKind()) {
+ case Decl::Enum: return CXCursor_EnumDecl;
+ case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
+ case Decl::Field: return CXCursor_FieldDecl;
+ case Decl::Function:
+ return CXCursor_FunctionDecl;
+ case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
+ case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
+ case Decl::ObjCClass:
+ // FIXME
+ return CXCursor_UnexposedDecl;
+ case Decl::ObjCForwardProtocol:
+ // FIXME
+ return CXCursor_UnexposedDecl;
+ case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
+ case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
+ case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
+ case Decl::ObjCMethod:
+ return cast<ObjCMethodDecl>(D)->isInstanceMethod()
+ ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
+ case Decl::CXXMethod: return CXCursor_CXXMethod;
+ case Decl::CXXConstructor: return CXCursor_Constructor;
+ case Decl::CXXDestructor: return CXCursor_Destructor;
+ case Decl::CXXConversion: return CXCursor_ConversionFunction;
+ case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
+ case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
+ case Decl::ParmVar: return CXCursor_ParmDecl;
+ case Decl::Typedef: return CXCursor_TypedefDecl;
+ case Decl::Var: return CXCursor_VarDecl;
+ case Decl::Namespace: return CXCursor_Namespace;
+ case Decl::NamespaceAlias: return CXCursor_NamespaceAlias;
+ case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter;
+ case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
+ case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
+ case Decl::FunctionTemplate: return CXCursor_FunctionTemplate;
+ case Decl::ClassTemplate: return CXCursor_ClassTemplate;
+ case Decl::ClassTemplatePartialSpecialization:
+ return CXCursor_ClassTemplatePartialSpecialization;
+ case Decl::UsingDirective: return CXCursor_UsingDirective;
- // Non-nested-name-specifiers precede nested-name-specifiers.
- if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
- return !X.StartsNestedNameSpecifier;
+ case Decl::Using:
+ case Decl::UnresolvedUsingValue:
+ case Decl::UnresolvedUsingTypename:
+ return CXCursor_UsingDeclaration;
- return false;
- }
- };
+ default:
+ if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ switch (TD->getTagKind()) {
+ case TTK_Struct: return CXCursor_StructDecl;
+ case TTK_Class: return CXCursor_ClassDecl;
+ case TTK_Union: return CXCursor_UnionDecl;
+ case TTK_Enum: return CXCursor_EnumDecl;
+ }
+ }
+ }
+
+ return CXCursor_UnexposedDecl;
}
static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
bool TargetTypeIsPointer = false) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
Results.EnterNewScope();
for (Preprocessor::macro_iterator M = PP.macro_begin(),
MEnd = PP.macro_end();
M != MEnd; ++M) {
- unsigned Priority = CCP_Macro;
-
- // Treat the "nil" and "NULL" macros as null pointer constants.
- if (M->first->isStr("nil") || M->first->isStr("NULL")) {
- Priority = CCP_Constant;
- if (TargetTypeIsPointer)
- Priority = Priority / CCF_SimilarTypeMatch;
- }
-
- Results.AddResult(Result(M->first, Priority));
+ Results.AddResult(Result(M->first,
+ getMacroUsagePriority(M->first->getName(),
+ TargetTypeIsPointer)));
}
Results.ExitScope();
}
+static void AddPrettyFunctionResults(const LangOptions &LangOpts,
+ ResultBuilder &Results) {
+ typedef CodeCompletionResult Result;
+
+ Results.EnterNewScope();
+ Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
+ Results.AddResult(Result("__FUNCTION__", CCP_Constant));
+ if (LangOpts.C99 || LangOpts.CPlusPlus0x)
+ Results.AddResult(Result("__func__", CCP_Constant));
+ Results.ExitScope();
+}
+
static void HandleCodeCompleteResults(Sema *S,
CodeCompleteConsumer *CodeCompleter,
- CodeCompleteConsumer::Result *Results,
- unsigned NumResults) {
- std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
-
+ CodeCompletionContext Context,
+ CodeCompletionResult *Results,
+ unsigned NumResults) {
if (CodeCompleter)
- CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+ CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
for (unsigned I = 0; I != NumResults; ++I)
Results[I].Destroy();
}
+static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S,
+ Sema::ParserCompletionContext PCC) {
+ switch (PCC) {
+ case Sema::PCC_Namespace:
+ return CodeCompletionContext::CCC_TopLevel;
+
+ case Sema::PCC_Class:
+ return CodeCompletionContext::CCC_ClassStructUnion;
+
+ case Sema::PCC_ObjCInterface:
+ return CodeCompletionContext::CCC_ObjCInterface;
+
+ case Sema::PCC_ObjCImplementation:
+ return CodeCompletionContext::CCC_ObjCImplementation;
+
+ case Sema::PCC_ObjCInstanceVariableList:
+ return CodeCompletionContext::CCC_ObjCIvarList;
+
+ case Sema::PCC_Template:
+ case Sema::PCC_MemberTemplate:
+ case Sema::PCC_RecoveryInFunction:
+ return CodeCompletionContext::CCC_Other;
+
+ case Sema::PCC_Expression:
+ case Sema::PCC_ForInit:
+ case Sema::PCC_Condition:
+ return CodeCompletionContext::CCC_Expression;
+
+ case Sema::PCC_Statement:
+ return CodeCompletionContext::CCC_Statement;
+
+ case Sema::PCC_Type:
+ return CodeCompletionContext::CCC_Type;
+ }
+
+ return CodeCompletionContext::CCC_Other;
+}
+
+/// \brief If we're in a C++ virtual member function, add completion results
+/// that invoke the functions we override, since it's common to invoke the
+/// overridden function as well as adding new functionality.
+///
+/// \param S The semantic analysis object for which we are generating results.
+///
+/// \param InContext This context in which the nested-name-specifier preceding
+/// the code-completion point
+static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
+ ResultBuilder &Results) {
+ // Look through blocks.
+ DeclContext *CurContext = S.CurContext;
+ while (isa<BlockDecl>(CurContext))
+ CurContext = CurContext->getParent();
+
+
+ CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
+ if (!Method || !Method->isVirtual())
+ return;
+
+ // We need to have names for all of the parameters, if we're going to
+ // generate a forwarding call.
+ for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+ PEnd = Method->param_end();
+ P != PEnd;
+ ++P) {
+ if (!(*P)->getDeclName())
+ return;
+ }
+
+ for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
+ MEnd = Method->end_overridden_methods();
+ M != MEnd; ++M) {
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
+ if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
+ continue;
+
+ // If we need a nested-name-specifier, add one now.
+ if (!InContext) {
+ NestedNameSpecifier *NNS
+ = getRequiredQualification(S.Context, CurContext,
+ Overridden->getDeclContext());
+ if (NNS) {
+ std::string Str;
+ llvm::raw_string_ostream OS(Str);
+ NNS->print(OS, S.Context.PrintingPolicy);
+ Pattern->AddTextChunk(OS.str());
+ }
+ } else if (!InContext->Equals(Overridden->getDeclContext()))
+ continue;
+
+ Pattern->AddTypedTextChunk(Overridden->getNameAsString());
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ bool FirstParam = true;
+ for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+ PEnd = Method->param_end();
+ P != PEnd; ++P) {
+ if (FirstParam)
+ FirstParam = false;
+ else
+ Pattern->AddChunk(CodeCompletionString::CK_Comma);
+
+ Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
+ }
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(CodeCompletionResult(Pattern,
+ CCP_SuperCompletion,
+ CXCursor_CXXMethod));
+ Results.Ignore(Overridden);
+ }
+}
+
void Sema::CodeCompleteOrdinaryName(Scope *S,
- CodeCompletionContext CompletionContext) {
- typedef CodeCompleteConsumer::Result Result;
- ResultBuilder Results(*this);
+ ParserCompletionContext CompletionContext) {
+ typedef CodeCompletionResult Result;
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
// Determine how to filter results, e.g., so that the names of
// values (functions, enumerators, function templates, etc.) are
// only allowed where we can have an expression.
switch (CompletionContext) {
- case CCC_Namespace:
- case CCC_Class:
- case CCC_ObjCInterface:
- case CCC_ObjCImplementation:
- case CCC_ObjCInstanceVariableList:
- case CCC_Template:
- case CCC_MemberTemplate:
+ case PCC_Namespace:
+ case PCC_Class:
+ case PCC_ObjCInterface:
+ case PCC_ObjCImplementation:
+ case PCC_ObjCInstanceVariableList:
+ case PCC_Template:
+ case PCC_MemberTemplate:
+ case PCC_Type:
Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
break;
- case CCC_Expression:
- case CCC_Statement:
- case CCC_ForInit:
- case CCC_Condition:
+ case PCC_Statement:
+ // For statements that are expressions, we prefer to call 'void' functions
+ // rather than functions that return a result, since then the result would
+ // be ignored.
+ Results.setPreferredType(Context.VoidTy);
+ // Fall through
+
+ case PCC_Expression:
+ case PCC_ForInit:
+ case PCC_Condition:
if (WantTypesInContext(CompletionContext, getLangOptions()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
+
+ if (getLangOptions().CPlusPlus)
+ MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
break;
- case CCC_RecoveryInFunction:
+ case PCC_RecoveryInFunction:
// Unfiltered
break;
}
+ // If we are in a C++ non-static member function, check the qualifiers on
+ // the member function to filter/prioritize the results list.
+ if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
+ if (CurMethod->isInstance())
+ Results.setObjectTypeQualifiers(
+ Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
+
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
- Results.EnterNewScope();
AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Results.ExitScope();
+ switch (CompletionContext) {
+ case PCC_Expression:
+ case PCC_Statement:
+ case PCC_RecoveryInFunction:
+ if (S->getFnParent())
+ AddPrettyFunctionResults(PP.getLangOptions(), Results);
+ break;
+
+ case PCC_Namespace:
+ case PCC_Class:
+ case PCC_ObjCInterface:
+ case PCC_ObjCImplementation:
+ case PCC_ObjCInstanceVariableList:
+ case PCC_Template:
+ case PCC_MemberTemplate:
+ case PCC_ForInit:
+ case PCC_Condition:
+ case PCC_Type:
+ break;
+ }
+
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results);
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ mapCodeCompletionContext(*this, CompletionContext),
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteDeclarator(Scope *S,
+ bool AllowNonIdentifiers,
+ bool AllowNestedNameSpecifiers) {
+ typedef CodeCompletionResult Result;
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Type qualifiers can come after names.
+ Results.AddResult(Result("const"));
+ Results.AddResult(Result("volatile"));
+ if (getLangOptions().C99)
+ Results.AddResult(Result("restrict"));
+
+ if (getLangOptions().CPlusPlus) {
+ if (AllowNonIdentifiers) {
+ Results.AddResult(Result("operator"));
+ }
+
+ // Add nested-name-specifiers.
+ if (AllowNestedNameSpecifiers) {
+ Results.allowNestedNameSpecifiers();
+ CodeCompletionDeclConsumer Consumer(Results, CurContext);
+ LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
+ CodeCompleter->includeGlobals());
+ }
+ }
+ Results.ExitScope();
+
+ // Note that we intentionally suppress macro results here, since we do not
+ // encourage using macros to produce the names of entities.
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ AllowNestedNameSpecifiers
+ ? CodeCompletionContext::CCC_PotentiallyQualifiedName
+ : CodeCompletionContext::CCC_Name,
+ Results.data(), Results.size());
}
+struct Sema::CodeCompleteExpressionData {
+ CodeCompleteExpressionData(QualType PreferredType = QualType())
+ : PreferredType(PreferredType), IntegralConstantExpression(false),
+ ObjCCollection(false) { }
+
+ QualType PreferredType;
+ bool IntegralConstantExpression;
+ bool ObjCCollection;
+ llvm::SmallVector<Decl *, 4> IgnoreDecls;
+};
+
/// \brief Perform code-completion in an expression context when we know what
/// type we're looking for.
-void Sema::CodeCompleteExpression(Scope *S, QualType T) {
- typedef CodeCompleteConsumer::Result Result;
+///
+/// \param IntegralConstantExpression Only permit integral constant
+/// expressions.
+void Sema::CodeCompleteExpression(Scope *S,
+ const CodeCompleteExpressionData &Data) {
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
- if (WantTypesInContext(CCC_Expression, getLangOptions()))
+ if (Data.ObjCCollection)
+ Results.setFilter(&ResultBuilder::IsObjCCollection);
+ else if (Data.IntegralConstantExpression)
+ Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
+ else if (WantTypesInContext(PCC_Expression, getLangOptions()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
- Results.setPreferredType(T.getNonReferenceType());
+
+ if (!Data.PreferredType.isNull())
+ Results.setPreferredType(Data.PreferredType.getNonReferenceType());
+
+ // Ignore any declarations that we were told that we don't care about.
+ for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
+ Results.Ignore(Data.IgnoreDecls[I]);
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
Results.EnterNewScope();
- AddOrdinaryNameResults(CCC_Expression, S, *this, Results);
+ AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
Results.ExitScope();
bool PreferredTypeIsPointer = false;
- if (!T.isNull())
- PreferredTypeIsPointer = T->isAnyPointerType() ||
- T->isMemberPointerType() || T->isBlockPointerType();
+ if (!Data.PreferredType.isNull())
+ PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
+ || Data.PreferredType->isMemberPointerType()
+ || Data.PreferredType->isBlockPointerType();
+ if (S->getFnParent() &&
+ !Data.ObjCCollection &&
+ !Data.IntegralConstantExpression)
+ AddPrettyFunctionResults(PP.getLangOptions(), Results);
+
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results, PreferredTypeIsPointer);
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext(CodeCompletionContext::CCC_Expression,
+ Data.PreferredType),
+ Results.data(),Results.size());
}
@@ -2303,7 +2725,7 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
bool AllowCategories,
DeclContext *CurContext,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Add properties in this container.
for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
@@ -2327,9 +2749,9 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
}
// Look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
- E = IFace->protocol_end();
- I != E; ++I)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ I = IFace->all_referenced_protocol_begin(),
+ E = IFace->all_referenced_protocol_end(); I != E; ++I)
AddObjCProperties(*I, AllowCategories, CurContext, Results);
// Look in the superclass.
@@ -2339,8 +2761,8 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
} else if (const ObjCCategoryDecl *Category
= dyn_cast<ObjCCategoryDecl>(Container)) {
// Look through protocols.
- for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
- PEnd = Category->protocol_end();
+ for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+ PEnd = Category->protocol_end();
P != PEnd; ++P)
AddObjCProperties(*P, AllowCategories, CurContext, Results);
}
@@ -2352,7 +2774,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
if (!BaseE || !CodeCompleter)
return;
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
Expr *Base = static_cast<Expr *>(BaseE);
QualType BaseType = Base->getType();
@@ -2361,7 +2783,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
if (const PointerType *Ptr = BaseType->getAs<PointerType>())
BaseType = Ptr->getPointeeType();
else if (BaseType->isObjCObjectPointerType())
- /*Do nothing*/ ;
+ /*Do nothing*/ ;
else
return;
}
@@ -2369,10 +2791,15 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
ResultBuilder Results(*this, &ResultBuilder::IsMember);
Results.EnterNewScope();
if (const RecordType *Record = BaseType->getAs<RecordType>()) {
+ // Indicate that we are performing a member access, and the cv-qualifiers
+ // for the base object type.
+ Results.setObjectTypeQualifiers(BaseType.getQualifiers());
+
// Access to a C/C++ class, struct, or union.
Results.allowNestedNameSpecifiers();
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
+ LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
+ CodeCompleter->includeGlobals());
if (getLangOptions().CPlusPlus) {
if (!Results.empty()) {
@@ -2420,7 +2847,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
if (Class) {
CodeCompletionDeclConsumer Consumer(Results, CurContext);
Results.setFilter(&ResultBuilder::IsObjCIvar);
- LookupVisibleDecls(Class, LookupMemberName, Consumer);
+ LookupVisibleDecls(Class, LookupMemberName, Consumer,
+ CodeCompleter->includeGlobals());
}
}
@@ -2429,27 +2857,35 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
Results.ExitScope();
// Hand off the results found for code completion.
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
+ BaseType),
+ Results.data(),Results.size());
}
void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
if (!CodeCompleter)
return;
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder::LookupFilter Filter = 0;
+ enum CodeCompletionContext::Kind ContextKind
+ = CodeCompletionContext::CCC_Other;
switch ((DeclSpec::TST)TagSpec) {
case DeclSpec::TST_enum:
Filter = &ResultBuilder::IsEnum;
+ ContextKind = CodeCompletionContext::CCC_EnumTag;
break;
case DeclSpec::TST_union:
Filter = &ResultBuilder::IsUnion;
+ ContextKind = CodeCompletionContext::CCC_UnionTag;
break;
case DeclSpec::TST_struct:
case DeclSpec::TST_class:
Filter = &ResultBuilder::IsClassOrStruct;
+ ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
break;
default:
@@ -2462,22 +2898,46 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
// First pass: look for tags.
Results.setFilter(Filter);
- LookupVisibleDecls(S, LookupTagName, Consumer);
+ LookupVisibleDecls(S, LookupTagName, Consumer,
+ CodeCompleter->includeGlobals());
- // Second pass: look for nested name specifiers.
- Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
- LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+ if (CodeCompleter->includeGlobals()) {
+ // Second pass: look for nested name specifiers.
+ Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
+ LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+ }
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+ if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+ Results.AddResult("const");
+ if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+ Results.AddResult("volatile");
+ if (getLangOptions().C99 &&
+ !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+ Results.AddResult("restrict");
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_TypeQualifiers,
+ Results.data(), Results.size());
}
void Sema::CodeCompleteCase(Scope *S) {
- if (getSwitchStack().empty() || !CodeCompleter)
+ if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
return;
- SwitchStmt *Switch = getSwitchStack().back();
- if (!Switch->getCond()->getType()->isEnumeralType())
+ SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
+ if (!Switch->getCond()->getType()->isEnumeralType()) {
+ CodeCompleteExpressionData Data(Switch->getCond()->getType());
+ Data.IntegralConstantExpression = true;
+ CodeCompleteExpression(S, Data);
return;
+ }
// Code-complete the cases of a switch statement over an enumeration type
// by providing the list of
@@ -2541,14 +3001,16 @@ void Sema::CodeCompleteCase(Scope *S) {
if (EnumeratorsSeen.count(*E))
continue;
- Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
+ Results.AddResult(CodeCompletionResult(*E, Qualifier),
CurContext, 0, false);
}
Results.ExitScope();
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results);
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Expression,
+ Results.data(),Results.size());
}
namespace {
@@ -2562,7 +3024,7 @@ namespace {
bool
operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
- return S.isBetterOverloadCandidate(X, Y, Loc);
+ return isBetterOverloadCandidate(S, X, Y, Loc);
}
};
}
@@ -2594,7 +3056,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
// Ignore type-dependent call expressions entirely.
if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
- CodeCompleteOrdinaryName(S, CCC_Expression);
+ CodeCompleteOrdinaryName(S, PCC_Expression);
return;
}
@@ -2678,7 +3140,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
}
if (ParamType.isNull())
- CodeCompleteOrdinaryName(S, CCC_Expression);
+ CodeCompleteOrdinaryName(S, PCC_Expression);
else
CodeCompleteExpression(S, ParamType);
@@ -2687,10 +3149,10 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
Results.size());
}
-void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
- ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
+void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
+ ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
if (!VD) {
- CodeCompleteOrdinaryName(S, CCC_Expression);
+ CodeCompleteOrdinaryName(S, PCC_Expression);
return;
}
@@ -2708,7 +3170,7 @@ void Sema::CodeCompleteReturn(Scope *S) {
ResultType = Method->getResultType();
if (ResultType.isNull())
- CodeCompleteOrdinaryName(S, CCC_Expression);
+ CodeCompleteOrdinaryName(S, PCC_Expression);
else
CodeCompleteExpression(S, ResultType);
}
@@ -2717,7 +3179,7 @@ void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
if (LHS)
CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
else
- CodeCompleteOrdinaryName(S, CCC_Expression);
+ CodeCompleteOrdinaryName(S, PCC_Expression);
}
void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
@@ -2735,16 +3197,29 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
return;
ResultBuilder Results(*this);
- CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
+ Results.EnterNewScope();
// The "template" keyword can follow "::" in the grammar, but only
// put it into the grammar if the nested-name-specifier is dependent.
NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
if (!Results.empty() && NNS->isDependent())
Results.AddResult("template");
+
+ // Add calls to overridden virtual functions, if there are any.
+ //
+ // FIXME: This isn't wonderful, because we don't know whether we're actually
+ // in a context that permits expressions. This is a general issue with
+ // qualified-id completions.
+ if (!EnteringContext)
+ MaybeAddOverrideCalls(*this, Ctx, Results);
+ Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ CodeCompletionDeclConsumer Consumer(Results, CurContext);
+ LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Name,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteUsing(Scope *S) {
@@ -2756,15 +3231,18 @@ void Sema::CodeCompleteUsing(Scope *S) {
// If we aren't in class scope, we could see the "namespace" keyword.
if (!S->isClassScope())
- Results.AddResult(CodeCompleteConsumer::Result("namespace"));
+ Results.AddResult(CodeCompletionResult("namespace"));
// After "using", we can see anything that would start a
// nested-name-specifier.
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteUsingDirective(Scope *S) {
@@ -2776,9 +3254,12 @@ void Sema::CodeCompleteUsingDirective(Scope *S) {
ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Results.EnterNewScope();
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Namespace,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteNamespaceDecl(Scope *S) {
@@ -2807,12 +3288,14 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) {
for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
NS != NSEnd; ++NS)
- Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
+ Results.AddResult(CodeCompletionResult(NS->second, 0),
CurContext, 0, false);
Results.ExitScope();
}
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
@@ -2822,15 +3305,18 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
// After "namespace", we expect to see a namespace or alias.
ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Namespace,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteOperatorName(Scope *S) {
if (!CodeCompleter)
return;
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this, &ResultBuilder::IsType);
Results.EnterNewScope();
@@ -2843,13 +3329,122 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
// Add any type names visible from the current scope
Results.allowNestedNameSpecifiers();
CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
// Add any type specifiers
AddTypeSpecifierResults(getLangOptions(), Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Type,
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
+ CXXBaseOrMemberInitializer** Initializers,
+ unsigned NumInitializers) {
+ CXXConstructorDecl *Constructor
+ = static_cast<CXXConstructorDecl *>(ConstructorD);
+ if (!Constructor)
+ return;
+
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Fill in any already-initialized fields or base classes.
+ llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+ llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
+ for (unsigned I = 0; I != NumInitializers; ++I) {
+ if (Initializers[I]->isBaseInitializer())
+ InitializedBases.insert(
+ Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
+ else
+ InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
+ }
+
+ // Add completions for base classes.
+ bool SawLastInitializer = (NumInitializers == 0);
+ CXXRecordDecl *ClassDecl = Constructor->getParent();
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ BaseEnd = ClassDecl->bases_end();
+ Base != BaseEnd; ++Base) {
+ if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+ SawLastInitializer
+ = NumInitializers > 0 &&
+ Initializers[NumInitializers - 1]->isBaseInitializer() &&
+ Context.hasSameUnqualifiedType(Base->getType(),
+ QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
+ continue;
+ }
+
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk(
+ Base->getType().getAsString(Context.PrintingPolicy));
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("args");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(CodeCompletionResult(Pattern,
+ SawLastInitializer? CCP_NextInitializer
+ : CCP_MemberDeclaration));
+ SawLastInitializer = false;
+ }
+
+ // Add completions for virtual base classes.
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+ BaseEnd = ClassDecl->vbases_end();
+ Base != BaseEnd; ++Base) {
+ if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+ SawLastInitializer
+ = NumInitializers > 0 &&
+ Initializers[NumInitializers - 1]->isBaseInitializer() &&
+ Context.hasSameUnqualifiedType(Base->getType(),
+ QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
+ continue;
+ }
+
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk(
+ Base->getType().getAsString(Context.PrintingPolicy));
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("args");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(CodeCompletionResult(Pattern,
+ SawLastInitializer? CCP_NextInitializer
+ : CCP_MemberDeclaration));
+ SawLastInitializer = false;
+ }
+
+ // Add completions for members.
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
+ SawLastInitializer
+ = NumInitializers > 0 &&
+ Initializers[NumInitializers - 1]->isMemberInitializer() &&
+ Initializers[NumInitializers - 1]->getMember() == *Field;
+ continue;
+ }
+
+ if (!Field->getDeclName())
+ continue;
+
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("args");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(CodeCompletionResult(Pattern,
+ SawLastInitializer? CCP_NextInitializer
+ : CCP_MemberDeclaration));
+ SawLastInitializer = false;
+ }
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Name,
+ Results.data(), Results.size());
}
// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
@@ -2858,7 +3453,7 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
static void AddObjCImplementationResults(const LangOptions &LangOpts,
ResultBuilder &Results,
bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Since we have an implementation, we can end it.
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
@@ -2883,7 +3478,7 @@ static void AddObjCImplementationResults(const LangOptions &LangOpts,
static void AddObjCInterfaceResults(const LangOptions &LangOpts,
ResultBuilder &Results,
bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Since we have an interface or protocol, we can end it.
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
@@ -2901,7 +3496,7 @@ static void AddObjCInterfaceResults(const LangOptions &LangOpts,
}
static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
CodeCompletionString *Pattern = 0;
// @class name ;
@@ -2946,9 +3541,9 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Results.AddResult(Result(Pattern));
}
-void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
bool InInterface) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
Results.EnterNewScope();
if (ObjCImpDecl)
@@ -2958,11 +3553,13 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
else
AddObjCTopLevelResults(Results, false);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
CodeCompletionString *Pattern = 0;
// @encode ( type-name )
@@ -2991,7 +3588,7 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
}
static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
CodeCompletionString *Pattern = 0;
if (Results.includeCodePatterns()) {
@@ -3041,7 +3638,7 @@ static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
static void AddObjCVisibilityResults(const LangOptions &LangOpts,
ResultBuilder &Results,
bool NeedAt) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
@@ -3054,7 +3651,9 @@ void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
Results.EnterNewScope();
AddObjCVisibilityResults(getLangOptions(), Results, false);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCAtStatement(Scope *S) {
@@ -3063,7 +3662,9 @@ void Sema::CodeCompleteObjCAtStatement(Scope *S) {
AddObjCStatementResults(Results, false);
AddObjCExpressionResults(Results, false);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCAtExpression(Scope *S) {
@@ -3071,7 +3672,9 @@ void Sema::CodeCompleteObjCAtExpression(Scope *S) {
Results.EnterNewScope();
AddObjCExpressionResults(Results, false);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
/// \brief Determine whether the addition of the given flag to an Objective-C
@@ -3110,37 +3713,39 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
unsigned Attributes = ODS.getPropertyAttributes();
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
Results.EnterNewScope();
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
- Results.AddResult(CodeCompleteConsumer::Result("readonly"));
+ Results.AddResult(CodeCompletionResult("readonly"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
- Results.AddResult(CodeCompleteConsumer::Result("assign"));
+ Results.AddResult(CodeCompletionResult("assign"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
- Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
+ Results.AddResult(CodeCompletionResult("readwrite"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
- Results.AddResult(CodeCompleteConsumer::Result("retain"));
+ Results.AddResult(CodeCompletionResult("retain"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
- Results.AddResult(CodeCompleteConsumer::Result("copy"));
+ Results.AddResult(CodeCompletionResult("copy"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
- Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
+ Results.AddResult(CodeCompletionResult("nonatomic"));
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
CodeCompletionString *Setter = new CodeCompletionString;
Setter->AddTypedTextChunk("setter");
Setter->AddTextChunk(" = ");
Setter->AddPlaceholderChunk("method");
- Results.AddResult(CodeCompleteConsumer::Result(Setter));
+ Results.AddResult(CodeCompletionResult(Setter));
}
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
CodeCompletionString *Getter = new CodeCompletionString;
Getter->AddTypedTextChunk("getter");
Getter->AddTextChunk(" = ");
Getter->AddPlaceholderChunk("method");
- Results.AddResult(CodeCompleteConsumer::Result(Getter));
+ Results.AddResult(CodeCompletionResult(Getter));
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
/// \brief Descripts the kind of Objective-C method that we want to find
@@ -3151,26 +3756,33 @@ enum ObjCMethodKind {
MK_OneArgSelector //< One-argument selector.
};
-static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
- ObjCMethodKind WantKind,
- IdentifierInfo **SelIdents,
- unsigned NumSelIdents) {
- Selector Sel = Method->getSelector();
+static bool isAcceptableObjCSelector(Selector Sel,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
if (NumSelIdents > Sel.getNumArgs())
return false;
-
+
switch (WantKind) {
- case MK_Any: break;
- case MK_ZeroArgSelector: return Sel.isUnarySelector();
- case MK_OneArgSelector: return Sel.getNumArgs() == 1;
+ case MK_Any: break;
+ case MK_ZeroArgSelector: return Sel.isUnarySelector();
+ case MK_OneArgSelector: return Sel.getNumArgs() == 1;
}
-
+
for (unsigned I = 0; I != NumSelIdents; ++I)
if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
return false;
-
+
return true;
}
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
+ NumSelIdents);
+}
/// \brief Add all of the Objective-C methods in the given Objective-C
/// container to the set of results.
@@ -3195,8 +3807,9 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
IdentifierInfo **SelIdents,
unsigned NumSelIdents,
DeclContext *CurContext,
- ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ ResultBuilder &Results,
+ bool InOriginalClass = true) {
+ typedef CodeCompletionResult Result;
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
MEnd = Container->meth_end();
M != MEnd; ++M) {
@@ -3209,6 +3822,8 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
Result R = Result(*M, 0);
R.StartParameter = NumSelIdents;
R.AllParametersAreInformative = (WantKind != MK_Any);
+ if (!InOriginalClass)
+ R.Priority += CCD_InBaseClass;
Results.MaybeAddResult(R, CurContext);
}
}
@@ -3223,13 +3838,13 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
- CurContext, Results);
+ CurContext, Results, false);
// Add methods in categories.
for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
CatDecl = CatDecl->getNextClassCategory()) {
AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
// Add a categories protocol methods.
const ObjCList<ObjCProtocolDecl> &Protocols
@@ -3238,37 +3853,36 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
E = Protocols.end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, false);
// Add methods in category implementations.
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
}
// Add methods in superclass.
if (IFace->getSuperClass())
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
- SelIdents, NumSelIdents, CurContext, Results);
+ SelIdents, NumSelIdents, CurContext, Results, false);
// Add methods in our implementation, if any.
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
- NumSelIdents, CurContext, Results);
+ NumSelIdents, CurContext, Results, InOriginalClass);
}
-void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
- DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
+ Decl **Methods,
unsigned NumMethods) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Try to find the interface where getters might live.
- ObjCInterfaceDecl *Class
- = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
+ ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
if (!Class) {
if (ObjCCategoryDecl *Category
- = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
+ = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
Class = Category->getClassInterface();
if (!Class)
@@ -3283,7 +3897,7 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
// pushed into DeclContexts early enough. Argh!
for (unsigned I = 0; I != NumMethods; ++I) {
if (ObjCMethodDecl *Method
- = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+ = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
if (Method->isInstanceMethod() &&
isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
Result R = Result(Method, 0);
@@ -3294,20 +3908,22 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
- DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
+ Decl **Methods,
unsigned NumMethods) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Try to find the interface where setters might live.
ObjCInterfaceDecl *Class
- = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
+ = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
if (!Class) {
if (ObjCCategoryDecl *Category
- = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
+ = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
Class = Category->getClassInterface();
if (!Class)
@@ -3322,7 +3938,7 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
// pushed into DeclContexts early enough. Argh!
for (unsigned I = 0; I != NumMethods; ++I) {
if (ObjCMethodDecl *Method
- = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+ = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
if (Method->isInstanceMethod() &&
isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
Result R = Result(Method, 0);
@@ -3334,7 +3950,54 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
+ typedef CodeCompletionResult Result;
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Add context-sensitive, Objective-C parameter-passing keywords.
+ bool AddedInOut = false;
+ if ((DS.getObjCDeclQualifier() &
+ (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
+ Results.AddResult("in");
+ Results.AddResult("inout");
+ AddedInOut = true;
+ }
+ if ((DS.getObjCDeclQualifier() &
+ (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
+ Results.AddResult("out");
+ if (!AddedInOut)
+ Results.AddResult("inout");
+ }
+ if ((DS.getObjCDeclQualifier() &
+ (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
+ ObjCDeclSpec::DQ_Oneway)) == 0) {
+ Results.AddResult("bycopy");
+ Results.AddResult("byref");
+ Results.AddResult("oneway");
+ }
+
+ // Add various builtin type names and specifiers.
+ AddOrdinaryNameResults(PCC_Type, S, *this, Results);
+ Results.ExitScope();
+
+ // Add the various type names
+ Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
+ CodeCompletionDeclConsumer Consumer(Results, CurContext);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
+
+ if (CodeCompleter->includeMacros())
+ AddMacroResults(PP, Results);
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Type,
+ Results.data(), Results.size());
}
/// \brief When we have an expression with type "id", we may assume
@@ -3407,28 +4070,138 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
.Default(0);
}
+// Add a special completion for a message send to "super", which fills in the
+// most likely case of forwarding all of our arguments to the superclass
+// function.
+///
+/// \param S The semantic analysis object.
+///
+/// \param S NeedSuperKeyword Whether we need to prefix this completion with
+/// the "super" keyword. Otherwise, we just need to provide the arguments.
+///
+/// \param SelIdents The identifiers in the selector that have already been
+/// provided as arguments for a send to "super".
+///
+/// \param NumSelIdents The number of identifiers in \p SelIdents.
+///
+/// \param Results The set of results to augment.
+///
+/// \returns the Objective-C method declaration that would be invoked by
+/// this "super" completion. If NULL, no completion was added.
+static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents,
+ ResultBuilder &Results) {
+ ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
+ if (!CurMethod)
+ return 0;
+
+ ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
+ if (!Class)
+ return 0;
+
+ // Try to find a superclass method with the same selector.
+ ObjCMethodDecl *SuperMethod = 0;
+ while ((Class = Class->getSuperClass()) && !SuperMethod)
+ SuperMethod = Class->getMethod(CurMethod->getSelector(),
+ CurMethod->isInstanceMethod());
+
+ if (!SuperMethod)
+ return 0;
+
+ // Check whether the superclass method has the same signature.
+ if (CurMethod->param_size() != SuperMethod->param_size() ||
+ CurMethod->isVariadic() != SuperMethod->isVariadic())
+ return 0;
+
+ for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
+ CurPEnd = CurMethod->param_end(),
+ SuperP = SuperMethod->param_begin();
+ CurP != CurPEnd; ++CurP, ++SuperP) {
+ // Make sure the parameter types are compatible.
+ if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(),
+ (*SuperP)->getType()))
+ return 0;
+
+ // Make sure we have a parameter name to forward!
+ if (!(*CurP)->getIdentifier())
+ return 0;
+ }
+
+ // We have a superclass method. Now, form the send-to-super completion.
+ CodeCompletionString *Pattern = new CodeCompletionString;
+
+ // Give this completion a return type.
+ AddResultTypeChunk(S.Context, SuperMethod, Pattern);
+
+ // If we need the "super" keyword, add it (plus some spacing).
+ if (NeedSuperKeyword) {
+ Pattern->AddTypedTextChunk("super");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ }
+
+ Selector Sel = CurMethod->getSelector();
+ if (Sel.isUnarySelector()) {
+ if (NeedSuperKeyword)
+ Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+ else
+ Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+ } else {
+ ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
+ for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
+ if (I > NumSelIdents)
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+
+ if (I < NumSelIdents)
+ Pattern->AddInformativeChunk(
+ Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+ else if (NeedSuperKeyword || I > NumSelIdents) {
+ Pattern->AddTextChunk(
+ Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+ Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
+ } else {
+ Pattern->AddTypedTextChunk(
+ Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+ Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
+ }
+ }
+ }
+
+ Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
+ SuperMethod->isInstanceMethod()
+ ? CXCursor_ObjCInstanceMethodDecl
+ : CXCursor_ObjCClassMethodDecl));
+ return SuperMethod;
+}
+
void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
// Find anything that looks like it could be a message receiver.
Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
CodeCompletionDeclConsumer Consumer(Results, CurContext);
Results.EnterNewScope();
- LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ CodeCompleter->includeGlobals());
// If we are in an Objective-C method inside a class that has a superclass,
// add "super" as an option.
if (ObjCMethodDecl *Method = getCurMethodDecl())
if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
- if (Iface->getSuperClass())
+ if (Iface->getSuperClass()) {
Results.AddResult(Result("super"));
+
+ AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
+ }
Results.ExitScope();
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results);
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_ObjCMessageReceiver,
+ Results.data(), Results.size());
}
@@ -3454,10 +4227,11 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
// an instance method.
QualType SuperTy = Context.getObjCInterfaceType(CDecl);
SuperTy = Context.getObjCObjectPointerType(SuperTy);
- OwningExprResult Super
+ ExprResult Super
= Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
- SelIdents, NumSelIdents);
+ SelIdents, NumSelIdents,
+ /*IsSuper=*/true);
}
// Fall through to send to the superclass in CDecl.
@@ -3480,7 +4254,7 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
CXXScopeSpec SS;
UnqualifiedId id;
id.setIdentifier(Super, SuperLoc);
- OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
+ ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
SelIdents, NumSelIdents);
}
@@ -3488,17 +4262,24 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
// Fall through
}
- TypeTy *Receiver = 0;
+ ParsedType Receiver;
if (CDecl)
- Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+ Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
- NumSelIdents);
+ NumSelIdents, /*IsSuper=*/true);
}
-void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
IdentifierInfo **SelIdents,
unsigned NumSelIdents) {
- typedef CodeCompleteConsumer::Result Result;
+ CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents,
+ bool IsSuper) {
+ typedef CodeCompletionResult Result;
ObjCInterfaceDecl *CDecl = 0;
// If the given name refers to an interface type, retrieve the
@@ -3515,6 +4296,20 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
ResultBuilder Results(*this);
Results.EnterNewScope();
+ // If this is a send-to-super, try to add the special "super" send
+ // completion.
+ if (IsSuper) {
+ if (ObjCMethodDecl *SuperMethod
+ = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
+ Results))
+ Results.Ignore(SuperMethod);
+ }
+
+ // If we're inside an Objective-C method definition, prefer its selector to
+ // others.
+ if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+ Results.setPreferredSelector(CurMethod->getSelector());
+
if (CDecl)
AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
Results);
@@ -3522,25 +4317,23 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
// We're messaging "id" as a type; provide all class/factory methods.
// If we have an external source, load the entire class method
- // pool from the PCH file.
+ // pool from the AST file.
if (ExternalSource) {
for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
I != N; ++I) {
Selector Sel = ExternalSource->GetExternalSelector(I);
- if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
- InstanceMethodPool.count(Sel))
+ if (Sel.isNull() || MethodPool.count(Sel))
continue;
- ReadMethodPool(Sel, /*isInstance=*/false);
+ ReadMethodPool(Sel);
}
}
- for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
- M = FactoryMethodPool.begin(),
- MEnd = FactoryMethodPool.end();
- M != MEnd;
- ++M) {
- for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
+ for (GlobalMethodPool::iterator M = MethodPool.begin(),
+ MEnd = MethodPool.end();
+ M != MEnd; ++M) {
+ for (ObjCMethodList *MethList = &M->second.second;
+ MethList && MethList->Method;
MethList = MethList->Next) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
@@ -3555,13 +4348,22 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(), Results.size());
}
void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
IdentifierInfo **SelIdents,
unsigned NumSelIdents) {
- typedef CodeCompleteConsumer::Result Result;
+ CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents,
+ bool IsSuper) {
+ typedef CodeCompletionResult Result;
Expr *RecExpr = static_cast<Expr *>(Receiver);
@@ -3574,6 +4376,20 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
ResultBuilder Results(*this);
Results.EnterNewScope();
+ // If this is a send-to-super, try to add the special "super" send
+ // completion.
+ if (IsSuper) {
+ if (ObjCMethodDecl *SuperMethod
+ = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents,
+ Results))
+ Results.Ignore(SuperMethod);
+ }
+
+ // If we're inside an Objective-C method definition, prefer its selector to
+ // others.
+ if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+ Results.setPreferredSelector(CurMethod->getSelector());
+
// If we're messaging an expression with type "id" or "Class", check
// whether we know something special about the receiver that allows
// us to assume a more-specific receiver type.
@@ -3623,25 +4439,23 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
// about as code-completion results.
// If we have an external source, load the entire class method
- // pool from the PCH file.
+ // pool from the AST file.
if (ExternalSource) {
for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
I != N; ++I) {
Selector Sel = ExternalSource->GetExternalSelector(I);
- if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
- FactoryMethodPool.count(Sel))
+ if (Sel.isNull() || MethodPool.count(Sel))
continue;
- ReadMethodPool(Sel, /*isInstance=*/true);
+ ReadMethodPool(Sel);
}
}
- for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
- M = InstanceMethodPool.begin(),
- MEnd = InstanceMethodPool.end();
- M != MEnd;
- ++M) {
- for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
+ for (GlobalMethodPool::iterator M = MethodPool.begin(),
+ MEnd = MethodPool.end();
+ M != MEnd; ++M) {
+ for (ObjCMethodList *MethList = &M->second.first;
+ MethList && MethList->Method;
MethList = MethList->Next) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
@@ -3656,7 +4470,79 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCForCollection(Scope *S,
+ DeclGroupPtrTy IterationVar) {
+ CodeCompleteExpressionData Data;
+ Data.ObjCCollection = true;
+
+ if (IterationVar.getAsOpaquePtr()) {
+ DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
+ for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
+ if (*I)
+ Data.IgnoreDecls.push_back(*I);
+ }
+ }
+
+ CodeCompleteExpression(S, Data);
+}
+
+void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ // If we have an external source, load the entire class method
+ // pool from the AST file.
+ if (ExternalSource) {
+ for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+ I != N; ++I) {
+ Selector Sel = ExternalSource->GetExternalSelector(I);
+ if (Sel.isNull() || MethodPool.count(Sel))
+ continue;
+
+ ReadMethodPool(Sel);
+ }
+ }
+
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+ for (GlobalMethodPool::iterator M = MethodPool.begin(),
+ MEnd = MethodPool.end();
+ M != MEnd; ++M) {
+
+ Selector Sel = M->first;
+ if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
+ continue;
+
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ if (Sel.isUnarySelector()) {
+ Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+ Results.AddResult(Pattern);
+ continue;
+ }
+
+ std::string Accumulator;
+ for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
+ if (I == NumSelIdents) {
+ if (!Accumulator.empty()) {
+ Pattern->AddInformativeChunk(Accumulator);
+ Accumulator.clear();
+ }
+ }
+
+ Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
+ Accumulator += ':';
+ }
+ Pattern->AddTypedTextChunk(Accumulator);
+ Results.AddResult(Pattern);
+ }
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_SelectorName,
+ Results.data(), Results.size());
}
/// \brief Add all of the protocol declarations that we find in the given
@@ -3664,7 +4550,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
bool OnlyForwardDeclarations,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
for (DeclContext::decl_iterator D = Ctx->decls_begin(),
DEnd = Ctx->decls_end();
@@ -3704,7 +4590,9 @@ void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_ObjCProtocolName,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
@@ -3716,7 +4604,9 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_ObjCProtocolName,
+ Results.data(),Results.size());
}
/// \brief Add all of the Objective-C interface declarations that we find in
@@ -3725,7 +4615,7 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
bool OnlyForwardDeclarations,
bool OnlyUnimplemented,
ResultBuilder &Results) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
for (DeclContext::decl_iterator D = Ctx->decls_begin(),
DEnd = Ctx->decls_end();
@@ -3757,7 +4647,9 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
false, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
@@ -3776,7 +4668,9 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
false, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
@@ -3788,13 +4682,15 @@ void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
true, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
IdentifierInfo *ClassName,
SourceLocation ClassNameLoc) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
@@ -3819,13 +4715,15 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Results.AddResult(Result(Category, 0), CurContext, 0, false);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
IdentifierInfo *ClassName,
SourceLocation ClassNameLoc) {
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
// Find the corresponding interface. If we couldn't find the interface, the
// program itself is ill-formed. However, we'll try to be helpful still by
@@ -3856,16 +4754,18 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
- typedef CodeCompleteConsumer::Result Result;
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
// Figure out where this @synthesize lives.
ObjCContainerDecl *Container
- = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
if (!Container ||
(!isa<ObjCImplementationDecl>(Container) &&
!isa<ObjCCategoryImplDecl>(Container)))
@@ -3889,18 +4789,20 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
false, CurContext, Results);
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
IdentifierInfo *PropertyName,
- DeclPtrTy ObjCImpDecl) {
- typedef CodeCompleteConsumer::Result Result;
+ Decl *ObjCImpDecl) {
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
// Figure out where this @synthesize lives.
ObjCContainerDecl *Container
- = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
if (!Container ||
(!isa<ObjCImplementationDecl>(Container) &&
!isa<ObjCCategoryImplDecl>(Container)))
@@ -3927,10 +4829,15 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
-typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
+// Mapping from selectors to the methods that implement that selector, along
+// with the "in original class" flag.
+typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> >
+ KnownMethodsMap;
/// \brief Find all of the methods that reside in the given container
/// (and its superclasses, protocols, etc.) that meet the given
@@ -3941,7 +4848,8 @@ static void FindImplementableMethods(ASTContext &Context,
bool WantInstanceMethods,
QualType ReturnType,
bool IsInImplementation,
- KnownMethodsMap &KnownMethods) {
+ KnownMethodsMap &KnownMethods,
+ bool InOriginalClass = true) {
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
// Recurse into protocols.
const ObjCList<ObjCProtocolDecl> &Protocols
@@ -3950,14 +4858,16 @@ static void FindImplementableMethods(ASTContext &Context,
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
// If we're not in the implementation of a class, also visit the
// superclass.
if (!IsInImplementation && IFace->getSuperClass())
FindImplementableMethods(Context, IFace->getSuperClass(),
WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ false);
// Add methods from any class extensions (but not from categories;
// those should go into category implementations).
@@ -3965,7 +4875,8 @@ static void FindImplementableMethods(ASTContext &Context,
Cat = Cat->getNextClassExtension())
FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
}
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
@@ -3976,7 +4887,8 @@ static void FindImplementableMethods(ASTContext &Context,
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods,
+ InOriginalClass);
}
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
@@ -3987,7 +4899,7 @@ static void FindImplementableMethods(ASTContext &Context,
E = Protocols.end();
I != E; ++I)
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- IsInImplementation, KnownMethods);
+ IsInImplementation, KnownMethods, false);
}
// Add methods in this container. This operation occurs last because
@@ -4001,15 +4913,15 @@ static void FindImplementableMethods(ASTContext &Context,
!Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
continue;
- KnownMethods[(*M)->getSelector()] = *M;
+ KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
}
}
}
void Sema::CodeCompleteObjCMethodDecl(Scope *S,
bool IsInstanceMethod,
- TypeTy *ReturnTy,
- DeclPtrTy IDecl) {
+ ParsedType ReturnTy,
+ Decl *IDecl) {
// Determine the return type of the method we're declaring, if
// provided.
QualType ReturnType = GetTypeFromParser(ReturnTy);
@@ -4017,7 +4929,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
// Determine where we should start searching for methods, and where we
ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
bool IsInImplementation = false;
- if (Decl *D = IDecl.getAs<Decl>()) {
+ if (Decl *D = IDecl) {
if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
SearchDecl = Impl->getClassInterface();
CurrentDecl = Impl;
@@ -4041,7 +4953,9 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
}
if (!SearchDecl || !CurrentDecl) {
- HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ 0, 0);
return;
}
@@ -4064,7 +4978,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
}
// Add declarations or definitions for each of the known methods.
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
Results.EnterNewScope();
PrintingPolicy Policy(Context.PrintingPolicy);
@@ -4072,7 +4986,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
for (KnownMethodsMap::iterator M = KnownMethods.begin(),
MEnd = KnownMethods.end();
M != MEnd; ++M) {
- ObjCMethodDecl *Method = M->second;
+ ObjCMethodDecl *Method = M->second.first;
CodeCompletionString *Pattern = new CodeCompletionString;
// If the result type was not already provided, add it to the
@@ -4100,7 +5014,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
Pattern->AddChunk(CodeCompletionString::CK_Colon);
else if (I < Sel.getNumArgs()) {
Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
- Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
+ Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
Pattern->AddChunk(CodeCompletionString::CK_Colon);
} else
break;
@@ -4113,14 +5027,14 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
Pattern->AddChunk(CodeCompletionString::CK_RightParen);
if (IdentifierInfo *Id = (*P)->getIdentifier())
- Pattern->AddTextChunk(Id->getName());
+ Pattern->AddTextChunk(Id->getName());
}
if (Method->isVariadic()) {
if (Method->param_size() > 0)
Pattern->AddChunk(CodeCompletionString::CK_Comma);
Pattern->AddTextChunk("...");
- }
+ }
if (IsInImplementation && Results.includeCodePatterns()) {
// We will be defining the method here, so add a compound statement.
@@ -4140,50 +5054,56 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
}
- Results.AddResult(Result(Pattern));
+ unsigned Priority = CCP_CodePattern;
+ if (!M->second.second)
+ Priority += CCD_InBaseClass;
+
+ Results.AddResult(Result(Pattern, Priority,
+ Method->isInstanceMethod()
+ ? CXCursor_ObjCInstanceMethodDecl
+ : CXCursor_ObjCClassMethodDecl));
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
}
void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
bool IsInstanceMethod,
bool AtParameterName,
- TypeTy *ReturnTy,
+ ParsedType ReturnTy,
IdentifierInfo **SelIdents,
unsigned NumSelIdents) {
- llvm::DenseMap<Selector, ObjCMethodList> &Pool
- = IsInstanceMethod? InstanceMethodPool : FactoryMethodPool;
-
// If we have an external source, load the entire class method
- // pool from the PCH file.
+ // pool from the AST file.
if (ExternalSource) {
for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
I != N; ++I) {
Selector Sel = ExternalSource->GetExternalSelector(I);
- if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
- FactoryMethodPool.count(Sel))
+ if (Sel.isNull() || MethodPool.count(Sel))
continue;
-
- ReadMethodPool(Sel, IsInstanceMethod);
+
+ ReadMethodPool(Sel);
}
}
// Build the set of methods we can see.
- typedef CodeCompleteConsumer::Result Result;
+ typedef CodeCompletionResult Result;
ResultBuilder Results(*this);
if (ReturnTy)
Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
-
+
Results.EnterNewScope();
- for (llvm::DenseMap<Selector, ObjCMethodList>::iterator M = Pool.begin(),
- MEnd = Pool.end();
- M != MEnd;
- ++M) {
- for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
+ for (GlobalMethodPool::iterator M = MethodPool.begin(),
+ MEnd = MethodPool.end();
+ M != MEnd; ++M) {
+ for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
+ &M->second.second;
+ MethList && MethList->Method;
MethList = MethList->Next) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
@@ -4212,5 +5132,270 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
}
Results.ExitScope();
- HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other,
+ Results.data(),Results.size());
+}
+
+void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // #if <condition>
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("if");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("condition");
+ Results.AddResult(Pattern);
+
+ // #ifdef <macro>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("ifdef");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("macro");
+ Results.AddResult(Pattern);
+
+ // #ifndef <macro>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("ifndef");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("macro");
+ Results.AddResult(Pattern);
+
+ if (InConditional) {
+ // #elif <condition>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("elif");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("condition");
+ Results.AddResult(Pattern);
+
+ // #else
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("else");
+ Results.AddResult(Pattern);
+
+ // #endif
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("endif");
+ Results.AddResult(Pattern);
+ }
+
+ // #include "header"
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("include");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("\"");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk("\"");
+ Results.AddResult(Pattern);
+
+ // #include <header>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("include");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("<");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk(">");
+ Results.AddResult(Pattern);
+
+ // #define <macro>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("define");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("macro");
+ Results.AddResult(Pattern);
+
+ // #define <macro>(<args>)
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("define");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("macro");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("args");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(Pattern);
+
+ // #undef <macro>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("undef");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("macro");
+ Results.AddResult(Pattern);
+
+ // #line <number>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("line");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("number");
+ Results.AddResult(Pattern);
+
+ // #line <number> "filename"
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("line");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("number");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("\"");
+ Pattern->AddPlaceholderChunk("filename");
+ Pattern->AddTextChunk("\"");
+ Results.AddResult(Pattern);
+
+ // #error <message>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("error");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("message");
+ Results.AddResult(Pattern);
+
+ // #pragma <arguments>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("pragma");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("arguments");
+ Results.AddResult(Pattern);
+
+ if (getLangOptions().ObjC1) {
+ // #import "header"
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("import");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("\"");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk("\"");
+ Results.AddResult(Pattern);
+
+ // #import <header>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("import");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("<");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk(">");
+ Results.AddResult(Pattern);
+ }
+
+ // #include_next "header"
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("include_next");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("\"");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk("\"");
+ Results.AddResult(Pattern);
+
+ // #include_next <header>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("include_next");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddTextChunk("<");
+ Pattern->AddPlaceholderChunk("header");
+ Pattern->AddTextChunk(">");
+ Results.AddResult(Pattern);
+
+ // #warning <message>
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("warning");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddPlaceholderChunk("message");
+ Results.AddResult(Pattern);
+
+ // Note: #ident and #sccs are such crazy anachronisms that we don't provide
+ // completions for them. And __include_macros is a Clang-internal extension
+ // that we don't want to encourage anyone to use.
+
+ // FIXME: we don't support #assert or #unassert, so don't suggest them.
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_PreprocessorDirective,
+ Results.data(), Results.size());
+}
+
+void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
+ CodeCompleteOrdinaryName(S,
+ S->getFnParent()? Sema::PCC_RecoveryInFunction
+ : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
+ ResultBuilder Results(*this);
+ if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
+ // Add just the names of macros, not their arguments.
+ Results.EnterNewScope();
+ for (Preprocessor::macro_iterator M = PP.macro_begin(),
+ MEnd = PP.macro_end();
+ M != MEnd; ++M) {
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk(M->first->getName());
+ Results.AddResult(Pattern);
+ }
+ Results.ExitScope();
+ } else if (IsDefinition) {
+ // FIXME: Can we detect when the user just wrote an include guard above?
+ }
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ IsDefinition? CodeCompletionContext::CCC_MacroName
+ : CodeCompletionContext::CCC_MacroNameUse,
+ Results.data(), Results.size());
+}
+
+void Sema::CodeCompletePreprocessorExpression() {
+ ResultBuilder Results(*this);
+
+ if (!CodeCompleter || CodeCompleter->includeMacros())
+ AddMacroResults(PP, Results);
+
+ // defined (<macro>)
+ Results.EnterNewScope();
+ CodeCompletionString *Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("defined");
+ Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("macro");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.AddResult(Pattern);
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_PreprocessorExpression,
+ Results.data(), Results.size());
+}
+
+void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
+ IdentifierInfo *Macro,
+ MacroInfo *MacroInfo,
+ unsigned Argument) {
+ // FIXME: In the future, we could provide "overload" results, much like we
+ // do for function calls.
+
+ CodeCompleteOrdinaryName(S,
+ S->getFnParent()? Sema::PCC_RecoveryInFunction
+ : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompleteNaturalLanguage() {
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_NaturalLanguage,
+ 0, 0);
+}
+
+void Sema::GatherGlobalCodeCompletions(
+ llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
+ ResultBuilder Builder(*this);
+
+ if (!CodeCompleter || CodeCompleter->includeGlobals()) {
+ CodeCompletionDeclConsumer Consumer(Builder,
+ Context.getTranslationUnitDecl());
+ LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName,
+ Consumer);
+ }
+
+ if (!CodeCompleter || CodeCompleter->includeMacros())
+ AddMacroResults(PP, Builder);
+
+ Results.clear();
+ Results.insert(Results.end(),
+ Builder.data(), Builder.data() + Builder.size());
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c1c898fac5f9..f5e045a722a0 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11,19 +11,24 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
#include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Parse/Template.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -35,18 +40,10 @@
#include <cstring>
#include <functional>
using namespace clang;
+using namespace sema;
-/// getDeclName - Return a pretty name for the specified decl if possible, or
-/// an empty string if not. This is used for pretty crash reporting.
-std::string Sema::getDeclName(DeclPtrTy d) {
- Decl *D = d.getAs<Decl>();
- if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(D))
- return DN->getQualifiedNameAsString();
- return "";
-}
-
-Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
- return DeclGroupPtrTy::make(DeclGroupRef(Ptr.getAs<Decl>()));
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
+ return DeclGroupPtrTy::make(DeclGroupRef(Ptr));
}
/// \brief If the identifier refers to a type name within this scope,
@@ -60,14 +57,14 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
///
/// If name lookup results in an ambiguity, this routine will complain
/// and then return NULL.
-Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, CXXScopeSpec *SS,
- bool isClassName,
- TypeTy *ObjectTypePtr) {
+ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec *SS,
+ bool isClassName,
+ ParsedType ObjectTypePtr) {
// Determine where we will perform name lookup.
DeclContext *LookupCtx = 0;
if (ObjectTypePtr) {
- QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+ QualType ObjectType = ObjectTypePtr.get();
if (ObjectType->isRecordType())
LookupCtx = computeDeclContext(ObjectType);
} else if (SS && SS->isNotEmpty()) {
@@ -85,22 +82,22 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// We therefore do not perform any name lookup if the result would
// refer to a member of an unknown specialization.
if (!isClassName)
- return 0;
+ return ParsedType();
// We know from the grammar that this name refers to a type,
// so build a dependent node to describe the type.
- return CheckTypenameType(ETK_None,
- (NestedNameSpecifier *)SS->getScopeRep(), II,
- SourceLocation(), SS->getRange(), NameLoc
- ).getAsOpaquePtr();
+ QualType T =
+ CheckTypenameType(ETK_None, SS->getScopeRep(), II,
+ SourceLocation(), SS->getRange(), NameLoc);
+ return ParsedType::make(T);
}
- return 0;
+ return ParsedType();
}
if (!LookupCtx->isDependentContext() &&
RequireCompleteDeclContext(*SS, LookupCtx))
- return 0;
+ return ParsedType();
}
// FIXME: LookupNestedNameSpecifierName isn't the right kind of
@@ -136,7 +133,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::FoundOverloaded:
case LookupResult::FoundUnresolvedValue:
Result.suppressDiagnostics();
- return 0;
+ return ParsedType();
case LookupResult::Ambiguous:
// Recover from type-hiding ambiguities by hiding the type. We'll
@@ -146,7 +143,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// that only makes sense if the identifier was treated like a type.
if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
Result.suppressDiagnostics();
- return 0;
+ return ParsedType();
}
// Look to see if we have a type anywhere in the list of results.
@@ -168,7 +165,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// will produce the ambiguity, or will complain that it expected
// a type name.
Result.suppressDiagnostics();
- return 0;
+ return ParsedType();
}
// We found a type within the ambiguous lookup; diagnose the
@@ -199,10 +196,10 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
} else {
// If it's not plausibly a type, suppress diagnostics.
Result.suppressDiagnostics();
- return 0;
+ return ParsedType();
}
- return T.getAsOpaquePtr();
+ return ParsedType::make(T);
}
/// isTagName() - This method is called *for error recovery purposes only*
@@ -233,9 +230,9 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
SourceLocation IILoc,
Scope *S,
CXXScopeSpec *SS,
- TypeTy *&SuggestedType) {
+ ParsedType &SuggestedType) {
// We don't have anything to suggest (yet).
- SuggestedType = 0;
+ SuggestedType = ParsedType();
// There may have been a typo in the name of the type. Look up typo
// results, in case we have something that we can suggest.
@@ -282,7 +279,8 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
CXXScopeSpec EmptySS;
TemplateTy TemplateResult;
bool MemberOfUnknownSpecialization;
- if (isTemplateName(S, SS ? *SS : EmptySS, Name, 0, true, TemplateResult,
+ if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false,
+ Name, ParsedType(), true, TemplateResult,
MemberOfUnknownSpecialization) == TNK_Type_template) {
TemplateName TplName = TemplateResult.getAsVal<TemplateName>();
Diag(IILoc, diag::err_template_missing_args) << TplName;
@@ -343,8 +341,10 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) {
return DC;
}
+ // ObjCMethodDecls are parsed (for some reason) outside the context
+ // of the class.
if (isa<ObjCMethodDecl>(DC))
- return Context.getTranslationUnitDecl();
+ return DC->getLexicalParent()->getLexicalParent();
return DC->getLexicalParent();
}
@@ -360,6 +360,7 @@ void Sema::PopDeclContext() {
assert(CurContext && "DeclContext imbalance!");
CurContext = getContainingDC(CurContext);
+ assert(CurContext && "Popped translation unit!");
}
/// EnterDeclaratorContext - Used when we must lookup names in the context
@@ -458,8 +459,8 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
IEnd = IdResolver.end();
for (; I != IEnd; ++I) {
- if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
- S->RemoveDecl(DeclPtrTy::make(*I));
+ if (S->isDeclScope(*I) && D->declarationReplaces(*I)) {
+ S->RemoveDecl(*I);
IdResolver.RemoveDecl(*I);
// Should only need to replace one decl.
@@ -467,7 +468,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
}
}
- S->AddDecl(DeclPtrTy::make(D));
+ S->AddDecl(D);
IdResolver.AddDecl(D);
}
@@ -475,6 +476,17 @@ bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
return IdResolver.isDeclInScope(D, Ctx, Context, S);
}
+Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) {
+ DeclContext *TargetDC = DC->getPrimaryContext();
+ do {
+ if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
+ if (ScopeDC->getPrimaryContext() == TargetDC)
+ return S;
+ } while ((S = S->getParent()));
+
+ return 0;
+}
+
static bool isOutOfScopePreviousDeclaration(NamedDecl *,
DeclContext*,
ASTContext&);
@@ -517,6 +529,90 @@ static void RemoveUsingDecls(LookupResult &R) {
F.done();
}
+/// \brief Check for this common pattern:
+/// @code
+/// class S {
+/// S(const S&); // DO NOT IMPLEMENT
+/// void operator=(const S&); // DO NOT IMPLEMENT
+/// };
+/// @endcode
+static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) {
+ // FIXME: Should check for private access too but access is set after we get
+ // the decl here.
+ if (D->isThisDeclarationADefinition())
+ return false;
+
+ if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+ return CD->isCopyConstructor();
+ return D->isCopyAssignment();
+}
+
+bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
+ assert(D);
+
+ if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>())
+ return false;
+
+ // Ignore class templates.
+ if (D->getDeclContext()->isDependentContext())
+ return false;
+
+ // We warn for unused decls internal to the translation unit.
+ if (D->getLinkage() == ExternalLinkage)
+ return false;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD))
+ return false;
+ } else {
+ // 'static inline' functions are used in headers; don't warn.
+ if (FD->getStorageClass() == SC_Static &&
+ FD->isInlineSpecified())
+ return false;
+ }
+
+ if (FD->isThisDeclarationADefinition())
+ return !Context.DeclMustBeEmitted(FD);
+ return true;
+ }
+
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (VD->isStaticDataMember() &&
+ VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+
+ if ( VD->isFileVarDecl() &&
+ !VD->getType().isConstant(Context))
+ return !Context.DeclMustBeEmitted(VD);
+ }
+
+ return false;
+ }
+
+ void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) {
+ if (!D)
+ return;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ const FunctionDecl *First = FD->getFirstDeclaration();
+ if (FD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+ return; // First should already be in the vector.
+ }
+
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ const VarDecl *First = VD->getFirstDeclaration();
+ if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+ return; // First should already be in the vector.
+ }
+
+ if (ShouldWarnIfUnusedFileScopedDecl(D))
+ UnusedFileScopedDecls.push_back(D);
+ }
+
static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
if (D->isInvalidDecl())
return false;
@@ -585,7 +681,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
- Decl *TmpD = (*I).getAs<Decl>();
+ Decl *TmpD = (*I);
assert(TmpD && "This decl didn't get pushed??");
assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
@@ -731,8 +827,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
FunctionDecl *New = FunctionDecl::Create(Context,
Context.getTranslationUnitDecl(),
Loc, II, R, /*TInfo=*/0,
- FunctionDecl::Extern,
- FunctionDecl::None, false,
+ SC_Extern,
+ SC_None, false,
/*hasPrototype=*/true);
New->setImplicit();
@@ -743,7 +839,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
FT->getArgType(i), /*TInfo=*/0,
- VarDecl::None, VarDecl::None, 0));
+ SC_None, SC_None, 0));
New->setParams(Params.data(), Params.size());
}
@@ -909,25 +1005,40 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
static bool
-DeclHasAttr(const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
- if (attr->getKind() == target->getKind())
+DeclHasAttr(const Decl *D, const Attr *A) {
+ const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+ for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+ if ((*i)->getKind() == A->getKind()) {
+ // FIXME: Don't hardcode this check
+ if (OA && isa<OwnershipAttr>(*i))
+ return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
return true;
+ }
return false;
}
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(New, attr) && attr->isMerged()) {
- Attr *NewAttr = attr->clone(C);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+ if (!Old->hasAttrs())
+ return;
+ // Ensure that any moving of objects within the allocated map is done before
+ // we process them.
+ if (!New->hasAttrs())
+ New->setAttrs(AttrVec());
+ for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+ ++i) {
+ // FIXME: Make this more general than just checking for Overloadable.
+ if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+ Attr *NewAttr = (*i)->clone(C);
NewAttr->setInherited(true);
New->addAttr(NewAttr);
}
}
}
+namespace {
+
/// Used in MergeFunctionDecl to keep track of function parameters in
/// C.
struct GNUCompatibleParamWarning {
@@ -936,6 +1047,7 @@ struct GNUCompatibleParamWarning {
QualType PromotedType;
};
+}
/// getSpecialMember - get the special member enum for a method.
Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
@@ -960,7 +1072,7 @@ static bool canRedefineFunction(const FunctionDecl *FD,
const LangOptions& LangOpts) {
return (LangOpts.GNUMode && !LangOpts.C99 && !LangOpts.CPlusPlus &&
FD->isInlineSpecified() &&
- FD->getStorageClass() == FunctionDecl::Extern);
+ FD->getStorageClass() == SC_Extern);
}
/// MergeFunctionDecl - We just parsed a function 'New' from
@@ -1014,8 +1126,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
// Don't complain about this if we're in GNU89 mode and the old function
// is an extern inline function.
if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) &&
- New->getStorageClass() == FunctionDecl::Static &&
- Old->getStorageClass() != FunctionDecl::Static &&
+ New->getStorageClass() == SC_Static &&
+ Old->getStorageClass() != SC_Static &&
!canRedefineFunction(Old, getLangOptions())) {
Diag(New->getLocation(), diag::err_static_non_static)
<< New;
@@ -1196,7 +1308,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
SourceLocation(), 0,
*ParamType, /*TInfo=*/0,
- VarDecl::None, VarDecl::None,
+ SC_None, SC_None,
0);
Param->setImplicit();
Params.push_back(Param);
@@ -1242,7 +1354,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
NewProto->getArgType(Idx))) {
ArgTypes.push_back(NewParm->getType());
} else if (Context.typesAreCompatible(OldParm->getType(),
- NewParm->getType())) {
+ NewParm->getType(),
+ /*CompareUnqualified=*/true)) {
GNUCompatibleParamWarning Warn
= { OldParm, NewParm, NewProto->getArgType(Idx) };
Warnings.push_back(Warn);
@@ -1257,8 +1370,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
diag::ext_param_promoted_not_compatible_with_prototype)
<< Warnings[Warn].PromotedType
<< Warnings[Warn].OldParm->getType();
- Diag(Warnings[Warn].OldParm->getLocation(),
- diag::note_previous_declaration);
+ if (Warnings[Warn].OldParm->getLocation().isValid())
+ Diag(Warnings[Warn].OldParm->getLocation(),
+ diag::note_previous_declaration);
}
New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
@@ -1309,11 +1423,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
/// \returns false
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
// Merge the attributes
- MergeAttributes(New, Old, Context);
+ MergeDeclAttributes(New, Old, Context);
// Merge the storage class.
- if (Old->getStorageClass() != FunctionDecl::Extern &&
- Old->getStorageClass() != FunctionDecl::None)
+ if (Old->getStorageClass() != SC_Extern &&
+ Old->getStorageClass() != SC_None)
New->setStorageClass(Old->getStorageClass());
// Merge "pure" flag.
@@ -1354,7 +1468,18 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
return New->setInvalidDecl();
}
- MergeAttributes(New, Old, Context);
+ // C++ [class.mem]p1:
+ // A member shall not be declared twice in the member-specification [...]
+ //
+ // Here, we need only consider static data members.
+ if (Old->isStaticDataMember() && !New->isOutOfLine()) {
+ Diag(New->getLocation(), diag::err_duplicate_member)
+ << New->getIdentifier();
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ New->setInvalidDecl();
+ }
+
+ MergeDeclAttributes(New, Old, Context);
// Merge the types
QualType MergedT;
@@ -1398,8 +1523,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
New->setType(MergedT);
// C99 6.2.2p4: Check if we have a static decl followed by a non-static.
- if (New->getStorageClass() == VarDecl::Static &&
- (Old->getStorageClass() == VarDecl::None || Old->hasExternalStorage())) {
+ if (New->getStorageClass() == SC_Static &&
+ (Old->getStorageClass() == SC_None || Old->hasExternalStorage())) {
Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New->setInvalidDecl();
@@ -1415,8 +1540,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
// identifier has external linkage.
if (New->hasExternalStorage() && Old->hasLinkage())
/* Okay */;
- else if (New->getStorageClass() != VarDecl::Static &&
- Old->getStorageClass() == VarDecl::Static) {
+ else if (New->getStorageClass() != SC_Static &&
+ Old->getStorageClass() == SC_Static) {
Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return New->setInvalidDecl();
@@ -1475,8 +1600,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
-Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
- DeclSpec &DS) {
+Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+ DeclSpec &DS) {
// FIXME: Error on auto/register at file scope
// FIXME: Error on inline/virtual/explicit
// FIXME: Warn on useless __thread
@@ -1489,10 +1614,10 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DS.getTypeSpecType() == DeclSpec::TST_struct ||
DS.getTypeSpecType() == DeclSpec::TST_union ||
DS.getTypeSpecType() == DeclSpec::TST_enum) {
- TagD = static_cast<Decl *>(DS.getTypeRep());
+ TagD = DS.getRepAsDecl();
if (!TagD) // We probably had an error
- return DeclPtrTy();
+ return 0;
// Note that the above type specs guarantee that the
// type rep is a Decl, whereas in many of the others
@@ -1513,14 +1638,12 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// If we're dealing with a class template decl, assume that the
// template routines are handling it.
if (TagD && isa<ClassTemplateDecl>(TagD))
- return DeclPtrTy();
+ return 0;
return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
}
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- // If there are attributes in the DeclSpec, apply them to the record.
- if (const AttributeList *AL = DS.getAttributes())
- ProcessDeclAttributeList(S, Record, AL);
+ ProcessDeclAttributeList(S, Record, DS.getAttributes());
if (!Record->getDeclName() && Record->isDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -1536,7 +1659,7 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// about them.
// FIXME: Should we support Microsoft's extensions in this area?
if (Record->getDeclName() && getLangOptions().Microsoft)
- return DeclPtrTy::make(Tag);
+ return Tag;
}
if (getLangOptions().CPlusPlus &&
@@ -1550,19 +1673,19 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
if (!DS.isMissingDeclaratorOk() &&
DS.getTypeSpecType() != DeclSpec::TST_error) {
// Warn about typedefs of enums without names, since this is an
- // extension in both Microsoft an GNU.
+ // extension in both Microsoft and GNU.
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef &&
Tag && isa<EnumDecl>(Tag)) {
Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name)
<< DS.getSourceRange();
- return DeclPtrTy::make(Tag);
+ return Tag;
}
Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
<< DS.getSourceRange();
}
- return DeclPtrTy::make(Tag);
+ return TagD;
}
/// We are trying to inject an anonymous member into the given scope;
@@ -1639,7 +1762,7 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
// considered to have been defined in the scope in which the
// anonymous union is declared.
Owner->makeDeclVisibleInContext(*F);
- S->AddDecl(Sema::DeclPtrTy::make(*F));
+ S->AddDecl(*F);
SemaRef.IdResolver.AddDecl(*F);
// That includes picking up the appropriate access specifier.
@@ -1660,58 +1783,38 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
/// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to
/// a VarDecl::StorageClass. Any error reporting is up to the caller:
-/// illegal input values are mapped to VarDecl::None.
-/// If the input declaration context is a linkage specification
-/// with no braces, then Extern is mapped to None.
-static VarDecl::StorageClass
-StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec,
- DeclContext *DC) {
+/// illegal input values are mapped to SC_None.
+static StorageClass
+StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
switch (StorageClassSpec) {
- case DeclSpec::SCS_unspecified: return VarDecl::None;
- case DeclSpec::SCS_extern:
- // If the current context is a C++ linkage specification
- // having no braces, then the keyword "extern" is properly part
- // of the linkage specification itself, rather than being
- // the written storage class specifier.
- return (DC && isa<LinkageSpecDecl>(DC) &&
- !cast<LinkageSpecDecl>(DC)->hasBraces())
- ? VarDecl::None : VarDecl::Extern;
- case DeclSpec::SCS_static: return VarDecl::Static;
- case DeclSpec::SCS_auto: return VarDecl::Auto;
- case DeclSpec::SCS_register: return VarDecl::Register;
- case DeclSpec::SCS_private_extern: return VarDecl::PrivateExtern;
+ case DeclSpec::SCS_unspecified: return SC_None;
+ case DeclSpec::SCS_extern: return SC_Extern;
+ case DeclSpec::SCS_static: return SC_Static;
+ case DeclSpec::SCS_auto: return SC_Auto;
+ case DeclSpec::SCS_register: return SC_Register;
+ case DeclSpec::SCS_private_extern: return SC_PrivateExtern;
// Illegal SCSs map to None: error reporting is up to the caller.
case DeclSpec::SCS_mutable: // Fall through.
- case DeclSpec::SCS_typedef: return VarDecl::None;
+ case DeclSpec::SCS_typedef: return SC_None;
}
llvm_unreachable("unknown storage class specifier");
}
/// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to
-/// a FunctionDecl::StorageClass. Any error reporting is up to the caller:
-/// illegal input values are mapped to FunctionDecl::None.
-/// If the input declaration context is a linkage specification
-/// with no braces, then Extern is mapped to None.
-static FunctionDecl::StorageClass
-StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec,
- DeclContext *DC) {
+/// a StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to SC_None.
+static StorageClass
+StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
switch (StorageClassSpec) {
- case DeclSpec::SCS_unspecified: return FunctionDecl::None;
- case DeclSpec::SCS_extern:
- // If the current context is a C++ linkage specification
- // having no braces, then the keyword "extern" is properly part
- // of the linkage specification itself, rather than being
- // the written storage class specifier.
- return (DC && isa<LinkageSpecDecl>(DC) &&
- !cast<LinkageSpecDecl>(DC)->hasBraces())
- ? FunctionDecl::None : FunctionDecl::Extern;
- case DeclSpec::SCS_static: return FunctionDecl::Static;
- case DeclSpec::SCS_private_extern: return FunctionDecl::PrivateExtern;
+ case DeclSpec::SCS_unspecified: return SC_None;
+ case DeclSpec::SCS_extern: return SC_Extern;
+ case DeclSpec::SCS_static: return SC_Static;
+ case DeclSpec::SCS_private_extern: return SC_PrivateExtern;
// Illegal SCSs map to None: error reporting is up to the caller.
case DeclSpec::SCS_auto: // Fall through.
case DeclSpec::SCS_mutable: // Fall through.
case DeclSpec::SCS_register: // Fall through.
- case DeclSpec::SCS_typedef: return FunctionDecl::None;
+ case DeclSpec::SCS_typedef: return SC_None;
}
llvm_unreachable("unknown storage class specifier");
}
@@ -1720,9 +1823,9 @@ StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec,
/// anonymous structure or union. Anonymous unions are a C++ feature
/// (C++ [class.union]) and a GNU C extension; anonymous structures
/// are a GNU C and GNU C++ extension.
-Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
- AccessSpecifier AS,
- RecordDecl *Record) {
+Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+ AccessSpecifier AS,
+ RecordDecl *Record) {
DeclContext *Owner = Record->getDeclContext();
// Diagnose whether this anonymous struct/union is an extension.
@@ -1782,6 +1885,9 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
<< (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected);
Invalid = true;
}
+
+ if (CheckNontrivialField(FD))
+ Invalid = true;
} else if ((*Mem)->isImplicit()) {
// Any implicit members are fine.
} else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
@@ -1845,17 +1951,17 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
assert(SCSpec != DeclSpec::SCS_typedef &&
"Parser allowed 'typedef' as storage class VarDecl.");
- VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+ VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
if (SCSpec == DeclSpec::SCS_mutable) {
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(Record->getLocation(), diag::err_mutable_nonmember);
Invalid = true;
- SC = VarDecl::None;
+ SC = SC_None;
}
SCSpec = DS.getStorageClassSpecAsWritten();
VarDecl::StorageClass SCAsWritten
- = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+ = StorageClassSpecToVarDeclStorageClass(SCSpec);
Anon = VarDecl::Create(Context, Owner, Record->getLocation(),
/*IdentifierInfo=*/0,
@@ -1886,85 +1992,115 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
if (Invalid)
Anon->setInvalidDecl();
- return DeclPtrTy::make(Anon);
+ return Anon;
}
/// GetNameForDeclarator - Determine the full declaration name for the
/// given Declarator.
-DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {
return GetNameFromUnqualifiedId(D.getName());
}
-/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
-DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
- switch (Name.getKind()) {
- case UnqualifiedId::IK_Identifier:
- return DeclarationName(Name.Identifier);
-
- case UnqualifiedId::IK_OperatorFunctionId:
- return Context.DeclarationNames.getCXXOperatorName(
- Name.OperatorFunctionId.Operator);
-
- case UnqualifiedId::IK_LiteralOperatorId:
- return Context.DeclarationNames.getCXXLiteralOperatorName(
- Name.Identifier);
-
- case UnqualifiedId::IK_ConversionFunctionId: {
- QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXConversionFunctionName(
- Context.getCanonicalType(Ty));
- }
-
- case UnqualifiedId::IK_ConstructorName: {
- QualType Ty = GetTypeFromParser(Name.ConstructorName);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(Ty));
- }
-
- case UnqualifiedId::IK_ConstructorTemplateId: {
- // In well-formed code, we can only have a constructor
- // template-id that refers to the current context, so go there
- // to find the actual type being constructed.
- CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
- if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
- return DeclarationName();
+/// \brief Retrieves the declaration name from a parsed unqualified-id.
+DeclarationNameInfo
+Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+ DeclarationNameInfo NameInfo;
+ NameInfo.setLoc(Name.StartLocation);
- // Determine the type of the class being constructed.
- QualType CurClassType = Context.getTypeDeclType(CurClass);
+ switch (Name.getKind()) {
- // FIXME: Check two things: that the template-id names the same type as
- // CurClassType, and that the template-id does not occur when the name
- // was qualified.
+ case UnqualifiedId::IK_Identifier:
+ NameInfo.setName(Name.Identifier);
+ NameInfo.setLoc(Name.StartLocation);
+ return NameInfo;
+
+ case UnqualifiedId::IK_OperatorFunctionId:
+ NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
+ Name.OperatorFunctionId.Operator));
+ NameInfo.setLoc(Name.StartLocation);
+ NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc
+ = Name.OperatorFunctionId.SymbolLocations[0];
+ NameInfo.getInfo().CXXOperatorName.EndOpNameLoc
+ = Name.EndLocation.getRawEncoding();
+ return NameInfo;
+
+ case UnqualifiedId::IK_LiteralOperatorId:
+ NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
+ Name.Identifier));
+ NameInfo.setLoc(Name.StartLocation);
+ NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);
+ return NameInfo;
+
+ case UnqualifiedId::IK_ConversionFunctionId: {
+ TypeSourceInfo *TInfo;
+ QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);
+ if (Ty.isNull())
+ return DeclarationNameInfo();
+ NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName(
+ Context.getCanonicalType(Ty)));
+ NameInfo.setLoc(Name.StartLocation);
+ NameInfo.setNamedTypeInfo(TInfo);
+ return NameInfo;
+ }
+
+ case UnqualifiedId::IK_ConstructorName: {
+ TypeSourceInfo *TInfo;
+ QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);
+ if (Ty.isNull())
+ return DeclarationNameInfo();
+ NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(Ty)));
+ NameInfo.setLoc(Name.StartLocation);
+ NameInfo.setNamedTypeInfo(TInfo);
+ return NameInfo;
+ }
+
+ case UnqualifiedId::IK_ConstructorTemplateId: {
+ // In well-formed code, we can only have a constructor
+ // template-id that refers to the current context, so go there
+ // to find the actual type being constructed.
+ CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
+ if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
+ return DeclarationNameInfo();
+
+ // Determine the type of the class being constructed.
+ QualType CurClassType = Context.getTypeDeclType(CurClass);
+
+ // FIXME: Check two things: that the template-id names the same type as
+ // CurClassType, and that the template-id does not occur when the name
+ // was qualified.
+
+ NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(CurClassType)));
+ NameInfo.setLoc(Name.StartLocation);
+ // FIXME: should we retrieve TypeSourceInfo?
+ NameInfo.setNamedTypeInfo(0);
+ return NameInfo;
+ }
+
+ case UnqualifiedId::IK_DestructorName: {
+ TypeSourceInfo *TInfo;
+ QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);
+ if (Ty.isNull())
+ return DeclarationNameInfo();
+ NameInfo.setName(Context.DeclarationNames.getCXXDestructorName(
+ Context.getCanonicalType(Ty)));
+ NameInfo.setLoc(Name.StartLocation);
+ NameInfo.setNamedTypeInfo(TInfo);
+ return NameInfo;
+ }
+
+ case UnqualifiedId::IK_TemplateId: {
+ TemplateName TName = Name.TemplateId->Template.get();
+ SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
+ return Context.getNameForTemplate(TName, TNameLoc);
+ }
+
+ } // switch (Name.getKind())
- return Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(CurClassType));
- }
-
- case UnqualifiedId::IK_DestructorName: {
- QualType Ty = GetTypeFromParser(Name.DestructorName);
- if (Ty.isNull())
- return DeclarationName();
-
- return Context.DeclarationNames.getCXXDestructorName(
- Context.getCanonicalType(Ty));
- }
-
- case UnqualifiedId::IK_TemplateId: {
- TemplateName TName
- = TemplateName::getFromVoidPointer(Name.TemplateId->Template);
- return Context.getNameForTemplate(TName);
- }
- }
-
assert(false && "Unknown name kind");
- return DeclarationName();
+ return DeclarationNameInfo();
}
/// isNearlyMatchingFunction - Determine whether the C++ functions
@@ -2007,11 +2143,10 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
switch (DS.getTypeSpecType()) {
case DeclSpec::TST_typename:
case DeclSpec::TST_typeofType:
- case DeclSpec::TST_typeofExpr:
case DeclSpec::TST_decltype: {
// Grab the type from the parser.
TypeSourceInfo *TSI = 0;
- QualType T = S.GetTypeFromParser(DS.getTypeRep(), &TSI);
+ QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
if (T.isNull() || !T->isDependentType()) break;
// Make sure there's a type source info. This isn't really much
@@ -2025,8 +2160,16 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
if (!TSI) return true;
// Store the new type back in the decl spec.
- QualType LocType = S.CreateLocInfoType(TSI->getType(), TSI);
- DS.UpdateTypeRep(LocType.getAsOpaquePtr());
+ ParsedType LocType = S.CreateParsedType(TSI->getType(), TSI);
+ DS.UpdateTypeRep(LocType);
+ break;
+ }
+
+ case DeclSpec::TST_typeofExpr: {
+ Expr *E = DS.getRepAsExpr();
+ ExprResult Result = S.RebuildExprInCurrentInstantiation(E);
+ if (Result.isInvalid()) return true;
+ DS.UpdateExprRep(Result.get());
break;
}
@@ -2054,11 +2197,16 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
return false;
}
-Sema::DeclPtrTy
-Sema::HandleDeclarator(Scope *S, Declarator &D,
- MultiTemplateParamsArg TemplateParamLists,
- bool IsFunctionDefinition) {
- DeclarationName Name = GetNameForDeclarator(D);
+Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
+ return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
+}
+
+Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
+ MultiTemplateParamsArg TemplateParamLists,
+ bool IsFunctionDefinition) {
+ // TODO: consider using NameInfo for diagnostic.
+ DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+ DeclarationName Name = NameInfo.getName();
// All of these full declarators require an identifier. If it doesn't have
// one, the ParsedFreeStandingDeclSpec action should be used.
@@ -2067,7 +2215,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
Diag(D.getDeclSpec().getSourceRange().getBegin(),
diag::err_declarator_need_ident)
<< D.getDeclSpec().getSourceRange() << D.getSourceRange();
- return DeclPtrTy();
+ return 0;
}
// The scope passed in may not be a decl scope. Zip up the scope tree until
@@ -2091,14 +2239,14 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
diag::err_template_qualified_declarator_no_match)
<< (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep()
<< D.getCXXScopeSpec().getRange();
- return DeclPtrTy();
+ return 0;
}
bool IsDependentContext = DC->isDependentContext();
if (!IsDependentContext &&
RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
- return DeclPtrTy();
+ return 0;
if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
Diag(D.getIdentifierLoc(),
@@ -2122,7 +2270,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType R = TInfo->getType();
- LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
ForRedeclaration);
// See if this is a redefinition of a variable in the same scope.
@@ -2140,7 +2288,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
IsLinkageLookup = true;
} else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
IsLinkageLookup = true;
- else if (CurContext->getLookupContext()->isTranslationUnit() &&
+ else if (CurContext->getRedeclContext()->isTranslationUnit() &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
IsLinkageLookup = true;
@@ -2225,7 +2373,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
if (TemplateParamLists.size()) {
Diag(D.getIdentifierLoc(), diag::err_template_typedef);
- return DeclPtrTy();
+ return 0;
}
New = ActOnTypedefDeclarator(S, D, DC, R, TInfo, Previous, Redeclaration);
@@ -2240,14 +2388,14 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
}
if (New == 0)
- return DeclPtrTy();
+ return 0;
// If this has an identifier and is not an invalid redeclaration or
// function template specialization, add it to the scope stack.
- if (Name && !(Redeclaration && New->isInvalidDecl()))
+ if (New->getDeclName() && !(Redeclaration && New->isInvalidDecl()))
PushOnScopeChains(New, S);
- return DeclPtrTy::make(New);
+ return New;
}
/// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
@@ -2255,20 +2403,26 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
/// be errors (for GCC compatibility).
static QualType TryToFixInvalidVariablyModifiedType(QualType T,
ASTContext &Context,
- bool &SizeIsNegative) {
+ bool &SizeIsNegative,
+ llvm::APSInt &Oversized) {
// This method tries to turn a variable array into a constant
// array even when the size isn't an ICE. This is necessary
// for compatibility with code that depends on gcc's buggy
// constant expression folding, like struct {char x[(int)(char*)2];}
SizeIsNegative = false;
-
+ Oversized = 0;
+
+ if (T->isDependentType())
+ return QualType();
+
QualifierCollector Qs;
const Type *Ty = Qs.strip(T);
if (const PointerType* PTy = dyn_cast<PointerType>(Ty)) {
QualType Pointee = PTy->getPointeeType();
QualType FixedType =
- TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative);
+ TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative,
+ Oversized);
if (FixedType.isNull()) return FixedType;
FixedType = Context.getPointerType(FixedType);
return Qs.apply(FixedType);
@@ -2287,15 +2441,24 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
!EvalResult.Val.isInt())
return QualType();
+ // Check whether the array size is negative.
llvm::APSInt &Res = EvalResult.Val.getInt();
- if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) {
- // TODO: preserve the size expression in declarator info
- return Context.getConstantArrayType(VLATy->getElementType(),
- Res, ArrayType::Normal, 0);
+ if (Res.isSigned() && Res.isNegative()) {
+ SizeIsNegative = true;
+ return QualType();
}
- SizeIsNegative = true;
- return QualType();
+ // Check whether the array is too large to be addressed.
+ unsigned ActiveSizeBits
+ = ConstantArrayType::getNumAddressingBits(Context, VLATy->getElementType(),
+ Res);
+ if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+ Oversized = Res;
+ return QualType();
+ }
+
+ return Context.getConstantArrayType(VLATy->getElementType(),
+ Res, ArrayType::Normal, 0);
}
/// \brief Register the given locally-scoped external C declaration so
@@ -2320,11 +2483,11 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) {
// The previous declaration was found on the identifer resolver
// chain, so remove it from its scope.
- while (S && !S->isDeclScope(DeclPtrTy::make(PrevDecl)))
+ while (S && !S->isDeclScope(PrevDecl))
S = S->getParent();
if (S)
- S->RemoveDecl(DeclPtrTy::make(PrevDecl));
+ S->RemoveDecl(PrevDecl);
}
}
@@ -2382,24 +2545,20 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewTD, D);
- // Merge the decl with the existing one if appropriate. If the decl is
- // in an outer scope, it isn't the same thing.
- FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
- if (!Previous.empty()) {
- Redeclaration = true;
- MergeTypeDefDecl(NewTD, Previous);
- }
-
// C99 6.7.7p2: If a typedef name specifies a variably modified type
// then it shall have block scope.
+ // Note that variably modified types must be fixed before merging the decl so
+ // that redeclarations will match.
QualType T = NewTD->getUnderlyingType();
if (T->isVariablyModifiedType()) {
- FunctionNeedsScopeChecking() = true;
+ getCurFunction()->setHasBranchProtectedScope();
if (S->getFnParent() == 0) {
bool SizeIsNegative;
+ llvm::APSInt Oversized;
QualType FixedTy =
- TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+ TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+ Oversized);
if (!FixedTy.isNull()) {
Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
@@ -2408,6 +2567,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
else if (T->isVariableArrayType())
Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
+ else if (Oversized.getBoolValue())
+ Diag(D.getIdentifierLoc(), diag::err_array_too_large)
+ << Oversized.toString(10);
else
Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
NewTD->setInvalidDecl();
@@ -2415,10 +2577,18 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
}
+ // Merge the decl with the existing one if appropriate. If the decl is
+ // in an outer scope, it isn't the same thing.
+ FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
+ if (!Previous.empty()) {
+ Redeclaration = true;
+ MergeTypeDefDecl(NewTD, Previous);
+ }
+
// If this is the C FILE type, notify the AST context.
if (IdentifierInfo *II = NewTD->getIdentifier())
if (!NewTD->isInvalidDecl() &&
- NewTD->getDeclContext()->getLookupContext()->isTranslationUnit()) {
+ NewTD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
if (II->isStr("FILE"))
Context.setFILEDecl(NewTD);
else if (II->isStr("jmp_buf"))
@@ -2452,7 +2622,7 @@ static bool
isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
ASTContext &Context) {
if (!PrevDecl)
- return 0;
+ return false;
if (!PrevDecl->hasLinkage())
return false;
@@ -2464,30 +2634,25 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
// outside the innermost enclosing namespace scope, the block
// scope declaration declares that same entity and receives the
// linkage of the previous declaration.
- DeclContext *OuterContext = DC->getLookupContext();
+ DeclContext *OuterContext = DC->getRedeclContext();
if (!OuterContext->isFunctionOrMethod())
// This rule only applies to block-scope declarations.
return false;
- else {
- DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
- if (PrevOuterContext->isRecord())
- // We found a member function: ignore it.
- return false;
- else {
- // Find the innermost enclosing namespace for the new and
- // previous declarations.
- while (!OuterContext->isFileContext())
- OuterContext = OuterContext->getParent();
- while (!PrevOuterContext->isFileContext())
- PrevOuterContext = PrevOuterContext->getParent();
-
- // The previous declaration is in a different namespace, so it
- // isn't the same function.
- if (OuterContext->getPrimaryContext() !=
- PrevOuterContext->getPrimaryContext())
- return false;
- }
- }
+
+ DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
+ if (PrevOuterContext->isRecord())
+ // We found a member function: ignore it.
+ return false;
+
+ // Find the innermost enclosing namespace for the new and
+ // previous declarations.
+ OuterContext = OuterContext->getEnclosingNamespaceContext();
+ PrevOuterContext = PrevOuterContext->getEnclosingNamespaceContext();
+
+ // The previous declaration is in a different namespace, so it
+ // isn't the same function.
+ if (!OuterContext->Equals(PrevOuterContext))
+ return false;
}
return true;
@@ -2506,7 +2671,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
bool &Redeclaration) {
- DeclarationName Name = GetNameForDeclarator(D);
+ DeclarationName Name = GetNameForDeclarator(D).getName();
// Check that there are no default arguments (C++ only).
if (getLangOptions().CPlusPlus)
@@ -2515,17 +2680,17 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
assert(SCSpec != DeclSpec::SCS_typedef &&
"Parser allowed 'typedef' as storage class VarDecl.");
- VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+ VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
if (SCSpec == DeclSpec::SCS_mutable) {
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
D.setInvalidType();
- SC = VarDecl::None;
+ SC = SC_None;
}
SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
VarDecl::StorageClass SCAsWritten
- = StorageClassSpecToVarDeclStorageClass(SCSpec, DC);
+ = StorageClassSpecToVarDeclStorageClass(SCSpec);
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (!II) {
@@ -2539,11 +2704,11 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (!DC->isRecord() && S->getFnParent() == 0) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
- if (SC == VarDecl::Auto || SC == VarDecl::Register) {
+ if (SC == SC_Auto || SC == SC_Register) {
// If this is a register variable with an asm label specified, then this
// is a GNU extension.
- if (SC == VarDecl::Register && D.getAsmLabel())
+ if (SC == SC_Register && D.getAsmLabel())
Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
else
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
@@ -2552,14 +2717,14 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
if (DC->isRecord() && !CurContext->isRecord()) {
// This is an out-of-line definition of a static data member.
- if (SC == VarDecl::Static) {
+ if (SC == SC_Static) {
Diag(D.getDeclSpec().getStorageClassSpecLoc(),
diag::err_static_out_of_line)
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
- } else if (SC == VarDecl::None)
- SC = VarDecl::Static;
+ } else if (SC == SC_None)
+ SC = SC_Static;
}
- if (SC == VarDecl::Static) {
+ if (SC == SC_Static) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
if (RD->isLocalClass())
Diag(D.getIdentifierLoc(),
@@ -2613,7 +2778,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
SetNestedNameSpecifier(NewVD, D);
- if (NumMatchedTemplateParamLists > 0) {
+ if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
NewVD->setTemplateParameterListsInfo(Context,
NumMatchedTemplateParamLists,
(TemplateParameterList**)TemplateParamLists.release());
@@ -2639,7 +2804,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
+ Context, SE->getString()));
}
// Diagnose shadowed variables before filtering for scope.
@@ -2679,6 +2845,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewVD->setInvalidDecl();
// attributes declared post-definition are currently ignored
+ // FIXME: This should be handled in attribute merging, not
+ // here.
if (Previous.isSingleResult()) {
VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
if (Def && (Def = Def->getDefinition()) &&
@@ -2694,6 +2862,13 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
!NewVD->isInvalidDecl())
RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
+ // If there's a #pragma GCC visibility in scope, and this isn't a class
+ // member, set the visibility of this variable.
+ if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord())
+ AddPushedVisibilityAttribute(NewVD);
+
+ MarkUnusedFileScopedDecl(NewVD);
+
return NewVD;
}
@@ -2807,19 +2982,16 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
bool isVM = T->isVariablyModifiedType();
if (isVM || NewVD->hasAttr<CleanupAttr>() ||
- NewVD->hasAttr<BlocksAttr>() ||
- // FIXME: We need to diagnose jumps passed initialized variables in C++.
- // However, this turns on the scope checker for everything with a variable
- // which may impact compile time. See if we can find a better solution
- // to this, perhaps only checking functions that contain gotos in C++?
- (LangOpts.CPlusPlus && NewVD->hasLocalStorage()))
- FunctionNeedsScopeChecking() = true;
+ NewVD->hasAttr<BlocksAttr>())
+ getCurFunction()->setHasBranchProtectedScope();
if ((isVM && NewVD->hasLinkage()) ||
(T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
bool SizeIsNegative;
+ llvm::APSInt Oversized;
QualType FixedTy =
- TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+ TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+ Oversized);
if (FixedTy.isNull() && T->isVariableArrayType()) {
const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
@@ -2830,7 +3002,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
<< SizeRange;
- else if (NewVD->getStorageClass() == VarDecl::Static)
+ else if (NewVD->getStorageClass() == SC_Static)
Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
<< SizeRange;
else
@@ -2970,8 +3142,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
bool IsFunctionDefinition, bool &Redeclaration) {
assert(R.getTypePtr()->isFunctionType());
- DeclarationName Name = GetNameForDeclarator(D);
- FunctionDecl::StorageClass SC = FunctionDecl::None;
+ // TODO: consider using NameInfo for diagnostic.
+ DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+ DeclarationName Name = NameInfo.getName();
+ FunctionDecl::StorageClass SC = SC_None;
switch (D.getDeclSpec().getStorageClassSpec()) {
default: assert(0 && "Unknown storage class!");
case DeclSpec::SCS_auto:
@@ -2981,10 +3155,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
diag::err_typecheck_sclass_func);
D.setInvalidType();
break;
- case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
- case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
+ case DeclSpec::SCS_unspecified: SC = SC_None; break;
+ case DeclSpec::SCS_extern: SC = SC_Extern; break;
case DeclSpec::SCS_static: {
- if (CurContext->getLookupContext()->isFunctionOrMethod()) {
+ if (CurContext->getRedeclContext()->isFunctionOrMethod()) {
// C99 6.7.1p5:
// The declaration of an identifier for a function that has
// block scope shall have no explicit storage-class specifier
@@ -2992,12 +3166,12 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// See also (C++ [dcl.stc]p4).
Diag(D.getDeclSpec().getStorageClassSpecLoc(),
diag::err_static_block_func);
- SC = FunctionDecl::None;
+ SC = SC_None;
} else
- SC = FunctionDecl::Static;
+ SC = SC_Static;
break;
}
- case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
+ case DeclSpec::SCS_private_extern: SC = SC_PrivateExtern;break;
}
if (D.getDeclSpec().isThreadSpecified())
@@ -3010,7 +3184,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
FunctionDecl::StorageClass SCAsWritten
- = StorageClassSpecToFunctionDeclStorageClass(SCSpec, DC);
+ = StorageClassSpecToFunctionDeclStorageClass(SCSpec);
// Check that the return type is not an abstract class type.
// For record types, this is done by the AbstractClassUsageDiagnoser once
@@ -3050,7 +3224,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Create the new declaration
NewFD = CXXConstructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), Name, R, TInfo,
+ NameInfo, R, TInfo,
isExplicit, isInline,
/*isImplicitlyDeclared=*/false);
} else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
@@ -3060,7 +3234,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), Name, R,
+ NameInfo, R,
isInline,
/*isImplicitlyDeclared=*/false);
NewFD->setTypeSourceInfo(TInfo);
@@ -3085,7 +3259,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
CheckConversionDeclarator(D, R, SC);
NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), Name, R, TInfo,
+ NameInfo, R, TInfo,
isInline, isExplicit);
isVirtualOkay = true;
@@ -3103,7 +3277,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
return 0;
}
- bool isStatic = SC == FunctionDecl::Static;
+ bool isStatic = SC == SC_Static;
// [class.free]p1:
// Any allocation function for a class T is a static member
@@ -3120,7 +3294,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// This is a C++ method declaration.
NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
- D.getIdentifierLoc(), Name, R, TInfo,
+ NameInfo, R, TInfo,
isStatic, SCAsWritten, isInline);
isVirtualOkay = !isStatic;
@@ -3137,8 +3311,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
(!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(Context, DC,
- D.getIdentifierLoc(),
- Name, R, TInfo, SC, SCAsWritten, isInline,
+ NameInfo, R, TInfo, SC, SCAsWritten, isInline,
HasPrototype);
}
@@ -3212,7 +3385,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
}
- if (NumMatchedTemplateParamLists > 0) {
+ if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
NewFD->setTemplateParameterListsInfo(Context,
NumMatchedTemplateParamLists,
(TemplateParameterList**)TemplateParamLists.release());
@@ -3244,6 +3417,17 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
}
+ // C++ [dcl.fct.spec]p3:
+ // The inline specifier shall not appear on a block scope function declaration.
+ if (isInline && !NewFD->isInvalidDecl() && getLangOptions().CPlusPlus) {
+ if (CurContext->isFunctionOrMethod()) {
+ // 'inline' is not allowed on block scope function declaration.
+ Diag(D.getDeclSpec().getInlineSpecLoc(),
+ diag::err_inline_declaration_block_scope) << Name
+ << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
+ }
+ }
+
// C++ [dcl.fct.spec]p6:
// The explicit specifier shall be used only in the declaration of a
// constructor or conversion function within its class definition; see 12.3.1
@@ -3282,7 +3466,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewFD->setAccess(AS_public);
}
- if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
+ if (SC == SC_Static && isa<CXXMethodDecl>(NewFD) &&
!CurContext->isRecord()) {
// C++ [class.static]p1:
// A data or function member of a class may be declared static
@@ -3300,7 +3484,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+ SE->getString()));
}
// Copy the parameter declarations from the declarator D to the function
@@ -3316,9 +3501,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// already checks for that case.
if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
FTI.ArgInfo[0].Param &&
- FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType()) {
+ cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
// Empty arg list, don't push any params.
- ParmVarDecl *Param = FTI.ArgInfo[0].Param.getAs<ParmVarDecl>();
+ ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[0].Param);
// In C++, the empty parameter-type-list must be spelled "void"; a
// typedef of void is not permitted.
@@ -3328,7 +3513,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// FIXME: Leaks decl?
} else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+ ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
assert(Param->getDeclContext() != NewFD && "Was set before ?");
Param->setDeclContext(NewFD);
Params.push_back(Param);
@@ -3479,14 +3664,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// definition (C++ [dcl.meaning]p1).
// Note that this is not the case for explicit specializations of
// function templates or member functions of class templates, per
- // C++ [temp.expl.spec]p2.
+ // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
+ // for compatibility with old SWIG code which likes to generate them.
if (!IsFunctionDefinition && !isFriend &&
!isFunctionTemplateSpecialization && !isExplicitSpecialization) {
- Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
+ Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
- NewFD->setInvalidDecl();
- } else if (!Redeclaration &&
- !(isFriend && CurContext->isDependentContext())) {
+ }
+ if (!Redeclaration && !(isFriend && CurContext->isDependentContext())) {
// The user tried to provide an out-of-line definition for a
// function that is a member of a class or namespace, but there
// was no such member function declared (C++ [class.mfct]p2,
@@ -3526,6 +3711,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
ProcessDeclAttributes(S, NewFD, D);
// attributes declared post-definition are currently ignored
+ // FIXME: This should happen during attribute merging
if (Redeclaration && Previous.isSingleResult()) {
const FunctionDecl *Def;
FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
@@ -3537,7 +3723,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+ if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -3545,9 +3731,28 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (!Previous.empty())
Diag(Previous.getRepresentativeDecl()->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr());
+ NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
+ }
+
+ if (NewFD->hasAttr<OverloadableAttr>() &&
+ !NewFD->getType()->getAs<FunctionProtoType>()) {
+ Diag(NewFD->getLocation(),
+ diag::err_attribute_overloadable_no_prototype)
+ << NewFD;
+
+ // Turn this into a variadic function with no parameters.
+ const FunctionType *FT = NewFD->getType()->getAs<FunctionType>();
+ QualType R = Context.getFunctionType(FT->getResultType(),
+ 0, 0, true, 0, false, false, 0, 0,
+ FT->getExtInfo());
+ NewFD->setType(R);
}
+ // If there's a #pragma GCC visibility in scope, and this isn't a class
+ // member, set the visibility of this function.
+ if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord())
+ AddPushedVisibilityAttribute(NewFD);
+
// If this is a locally-scoped extern C function, update the
// map of such names.
if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
@@ -3563,17 +3768,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (FunctionTemplate)
return FunctionTemplate;
-
- // Keep track of static, non-inlined function definitions that
- // have not been used. We will warn later.
- // FIXME: Also include static functions declared but not defined.
- if (!NewFD->isInvalidDecl() && IsFunctionDefinition
- && !NewFD->isInlined() && NewFD->getLinkage() == InternalLinkage
- && !NewFD->isUsed() && !NewFD->hasAttr<UnusedAttr>()
- && !NewFD->hasAttr<ConstructorAttr>()
- && !NewFD->hasAttr<DestructorAttr>())
- UnusedStaticFuncs.push_back(NewFD);
-
+ MarkUnusedFileScopedDecl(NewFD);
+
return NewFD;
}
@@ -3597,8 +3793,14 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
bool &Redeclaration,
bool &OverloadableAttrRequired) {
// If NewFD is already known erroneous, don't do any of this checking.
- if (NewFD->isInvalidDecl())
+ if (NewFD->isInvalidDecl()) {
+ // If this is a class member, mark the class invalid immediately.
+ // This avoids some consistency errors later.
+ if (isa<CXXMethodDecl>(NewFD))
+ cast<CXXMethodDecl>(NewFD)->getParent()->setInvalidDecl();
+
return;
+ }
if (NewFD->getResultType()->isVariablyModifiedType()) {
// Functions returning a variably modified type violate C99 6.7.5.2p2
@@ -3634,27 +3836,9 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
Redeclaration = true;
OldDecl = Previous.getFoundDecl();
} else {
- if (!getLangOptions().CPlusPlus) {
+ if (!getLangOptions().CPlusPlus)
OverloadableAttrRequired = true;
- // Functions marked "overloadable" must have a prototype (that
- // we can't get through declaration merging).
- if (!NewFD->getType()->getAs<FunctionProtoType>()) {
- Diag(NewFD->getLocation(),
- diag::err_attribute_overloadable_no_prototype)
- << NewFD;
- Redeclaration = true;
-
- // Turn this into a variadic function with no parameters.
- QualType R = Context.getFunctionType(
- NewFD->getType()->getAs<FunctionType>()->getResultType(),
- 0, 0, true, 0, false, false, 0, 0,
- FunctionType::ExtInfo());
- NewFD->setType(R);
- return NewFD->setInvalidDecl();
- }
- }
-
switch (CheckOverload(S, NewFD, Previous, OldDecl,
/*NewIsUsingDecl*/ false)) {
case Ovl_Match:
@@ -3723,6 +3907,8 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(
Context.getCanonicalType(ClassType));
+// NewFD->getDeclName().dump();
+// Name.dump();
if (NewFD->getDeclName() != Name) {
Diag(NewFD->getLocation(), diag::err_destructor_name);
return NewFD->setInvalidDecl();
@@ -3750,12 +3936,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
AddOverriddenMethods(Method->getParent(), Method);
}
- // Additional checks for the destructor; make sure we do this after we
- // figure out whether the destructor is virtual.
- if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(NewFD))
- if (!Destructor->getParent()->isDependentType())
- CheckDestructor(Destructor);
-
// Extra checking for C++ overloaded operators (C++ [over.oper]).
if (NewFD->isOverloadedOperator() &&
CheckOverloadedOperatorDeclaration(NewFD))
@@ -3781,7 +3961,7 @@ void Sema::CheckMain(FunctionDecl* FD) {
// shall not appear in a declaration of main.
// static main is not an error under C99, but we should warn about it.
bool isInline = FD->isInlineSpecified();
- bool isStatic = FD->getStorageClass() == FunctionDecl::Static;
+ bool isStatic = FD->getStorageClass() == SC_Static;
if (isInline || isStatic) {
unsigned diagID = diag::warn_unusual_main_decl;
if (isInline || getLangOptions().CPlusPlus)
@@ -3874,22 +4054,21 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
// "may accept other forms of constant expressions" exception.
// (We never end up here for C++, so the constant expression
// rules there don't matter.)
- if (Init->isConstantInitializer(Context))
+ if (Init->isConstantInitializer(Context, false))
return false;
Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
<< Init->getSourceRange();
return true;
}
-void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init) {
- AddInitializerToDecl(dcl, move(init), /*DirectInit=*/false);
+void Sema::AddInitializerToDecl(Decl *dcl, Expr *init) {
+ AddInitializerToDecl(dcl, init, /*DirectInit=*/false);
}
/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
-void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
- Decl *RealDecl = dcl.getAs<Decl>();
+void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// If there is no declaration, there was an error parsing it. Just ignore
// the initializer.
if (RealDecl == 0)
@@ -3900,7 +4079,6 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
// distinguish between a normal initializer and a pure-specifier.
// Thus this grotesque test.
IntegerLiteral *IL;
- Expr *Init = static_cast<Expr *>(init.get());
if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
Context.getCanonicalType(IL->getType()) == Context.IntTy)
CheckPureMethod(Method, Init->getSourceRange());
@@ -3925,6 +4103,8 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
return;
}
+
+
// A definition must end up with a complete type, which means it must be
// complete with the restriction that an array type might be completed by the
// initializer; note that later code assumes this restriction.
@@ -3951,11 +4131,28 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
VDecl->setInvalidDecl();
return;
}
+
+ // C++ [class.static.data]p4
+ // If a static data member is of const integral or const
+ // enumeration type, its declaration in the class definition can
+ // specify a constant-initializer which shall be an integral
+ // constant expression (5.19). In that case, the member can appear
+ // in integral constant expressions. The member shall still be
+ // defined in a namespace scope if it is used in the program and the
+ // namespace scope definition shall not contain an initializer.
+ //
+ // We already performed a redefinition check above, but for static
+ // data members we also need to check whether there was an in-class
+ // declaration with an initializer.
+ const VarDecl* PrevInit = 0;
+ if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+ Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+ Diag(PrevInit->getLocation(), diag::note_previous_definition);
+ return;
+ }
- // Take ownership of the expression, now that we're sure we have somewhere
- // to put it.
- Expr *Init = init.takeAs<Expr>();
- assert(Init && "missing initializer");
+ if (getLangOptions().CPlusPlus && VDecl->hasLocalStorage())
+ getCurFunction()->setHasBranchProtectedScope();
// Capture the variable that is being initialized and the style of
// initialization.
@@ -3978,8 +4175,8 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
VDecl->setInvalidDecl();
} else if (!VDecl->isInvalidDecl()) {
InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&Init, 1),
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &Init, 1),
&DclT);
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
@@ -3991,7 +4188,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
// C++ 3.6.2p2, allow dynamic initialization of static initializers.
// Don't check invalid declarations to avoid emitting useless diagnostics.
if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
- if (VDecl->getStorageClass() == VarDecl::Static) // C99 6.7.8p4.
+ if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4.
CheckForConstantInitializer(Init, DclT);
}
}
@@ -4039,18 +4236,18 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
<< Init->getSourceRange();
VDecl->setInvalidDecl();
} else if (!VDecl->getType()->isDependentType())
- ImpCastExprToType(Init, VDecl->getType(), CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Init, VDecl->getType(), CK_IntegralCast);
}
}
} else if (VDecl->isFileVarDecl()) {
- if (VDecl->getStorageClass() == VarDecl::Extern &&
+ if (VDecl->getStorageClass() == SC_Extern &&
(!getLangOptions().CPlusPlus ||
!Context.getBaseElementType(VDecl->getType()).isConstQualified()))
Diag(VDecl->getLocation(), diag::warn_extern_init);
if (!VDecl->isInvalidDecl()) {
InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&Init, 1),
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &Init, 1),
&DclT);
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
@@ -4081,6 +4278,14 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
VDecl->setInit(Init);
if (getLangOptions().CPlusPlus) {
+ if (!VDecl->isInvalidDecl() &&
+ !VDecl->getDeclContext()->isDependentContext() &&
+ VDecl->hasGlobalStorage() && !VDecl->isStaticLocal() &&
+ !Init->isConstantInitializer(Context,
+ VDecl->getType()->isReferenceType()))
+ Diag(VDecl->getLocation(), diag::warn_global_constructor)
+ << Init->getSourceRange();
+
// Make sure we mark the destructor as used if necessary.
QualType InitType = VDecl->getType();
while (const ArrayType *Array = Context.getAsArrayType(InitType))
@@ -4095,10 +4300,9 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
/// ActOnInitializerError - Given that there was an error parsing an
/// initializer for the given declaration, try to return to some form
/// of sanity.
-void Sema::ActOnInitializerError(DeclPtrTy dcl) {
+void Sema::ActOnInitializerError(Decl *D) {
// Our main concern here is re-establishing invariants like "a
// variable's type is either dependent or complete".
- Decl *D = dcl.getAs<Decl>();
if (!D || D->isInvalidDecl()) return;
VarDecl *VD = dyn_cast<VarDecl>(D);
@@ -4127,10 +4331,8 @@ void Sema::ActOnInitializerError(DeclPtrTy dcl) {
// though.
}
-void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
+void Sema::ActOnUninitializedDecl(Decl *RealDecl,
bool TypeContainsUndeducedAuto) {
- Decl *RealDecl = dcl.getAs<Decl>();
-
// If there is no declaration, there was an error parsing it. Just ignore it.
if (RealDecl == 0)
return;
@@ -4190,7 +4392,7 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
ArrayT->getElementType(),
diag::err_illegal_decl_array_incomplete_type))
Var->setInvalidDecl();
- } else if (Var->getStorageClass() == VarDecl::Static) {
+ } else if (Var->getStorageClass() == SC_Static) {
// C99 6.9.2p3: If the declaration of an identifier for an object is
// a tentative definition and has internal linkage (C99 6.2.2p3), the
// declared type shall not be an incomplete type.
@@ -4221,15 +4423,15 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
return;
}
- // Provide a specific diagnostic for uninitialized variable
- // definitions with reference type.
- if (Type->isReferenceType()) {
- Diag(Var->getLocation(), diag::err_reference_var_requires_init)
- << Var->getDeclName()
- << SourceRange(Var->getLocation(), Var->getLocation());
- Var->setInvalidDecl();
- return;
- }
+ // Provide a specific diagnostic for uninitialized variable
+ // definitions with reference type.
+ if (Type->isReferenceType()) {
+ Diag(Var->getLocation(), diag::err_reference_var_requires_init)
+ << Var->getDeclName()
+ << SourceRange(Var->getLocation(), Var->getLocation());
+ Var->setInvalidDecl();
+ return;
+ }
// Do not attempt to type-check the default initializer for a
// variable with dependent type.
@@ -4271,17 +4473,30 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
// program is ill-formed.
// FIXME: DPG thinks it is very fishy that C++0x disables this.
} else {
+ // Check for jumps past the implicit initializer. C++0x
+ // clarifies that this applies to a "variable with automatic
+ // storage duration", not a "local variable".
+ if (getLangOptions().CPlusPlus && Var->hasLocalStorage())
+ getCurFunction()->setHasBranchProtectedScope();
+
InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
InitializationKind Kind
= InitializationKind::CreateDefault(Var->getLocation());
InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
- OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, 0, 0));
+ ExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, 0, 0));
if (Init.isInvalid())
Var->setInvalidDecl();
- else if (Init.get())
+ else if (Init.get()) {
Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
+
+ if (getLangOptions().CPlusPlus && !Var->isInvalidDecl() &&
+ Var->hasGlobalStorage() && !Var->isStaticLocal() &&
+ !Var->getDeclContext()->isDependentContext() &&
+ !Var->getInit()->isConstantInitializer(Context, false))
+ Diag(Var->getLocation(), diag::warn_global_constructor);
+ }
}
if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
@@ -4289,16 +4504,16 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
}
}
-Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
- DeclPtrTy *Group,
- unsigned NumDecls) {
+Sema::DeclGroupPtrTy
+Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+ Decl **Group, unsigned NumDecls) {
llvm::SmallVector<Decl*, 8> Decls;
if (DS.isTypeSpecOwned())
- Decls.push_back((Decl*)DS.getTypeRep());
+ Decls.push_back(DS.getRepAsDecl());
for (unsigned i = 0; i != NumDecls; ++i)
- if (Decl *D = Group[i].getAs<Decl>())
+ if (Decl *D = Group[i])
Decls.push_back(D);
return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
@@ -4308,16 +4523,15 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
/// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
/// to introduce parameters into function prototype scope.
-Sema::DeclPtrTy
-Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
+Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
const DeclSpec &DS = D.getDeclSpec();
// Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
- VarDecl::StorageClass StorageClass = VarDecl::None;
- VarDecl::StorageClass StorageClassAsWritten = VarDecl::None;
+ VarDecl::StorageClass StorageClass = SC_None;
+ VarDecl::StorageClass StorageClassAsWritten = SC_None;
if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
- StorageClass = VarDecl::Register;
- StorageClassAsWritten = VarDecl::Register;
+ StorageClass = SC_Register;
+ StorageClassAsWritten = SC_Register;
} else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
Diag(DS.getStorageClassSpecLoc(),
diag::err_invalid_storage_class_in_func_decl);
@@ -4358,7 +4572,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
// Just pretend that we didn't see the previous declaration.
PrevDecl = 0;
- } else if (S->isDeclScope(DeclPtrTy::make(PrevDecl))) {
+ } else if (S->isDeclScope(PrevDecl)) {
Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
@@ -4389,7 +4603,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
}
// Add the parameter declaration into this scope.
- S->AddDecl(DeclPtrTy::make(New));
+ S->AddDecl(New);
if (II)
IdResolver.AddDecl(New);
@@ -4398,7 +4612,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
if (New->hasAttr<BlocksAttr>()) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
}
- return DeclPtrTy::make(New);
+ return New;
}
/// \brief Synthesizes a variable for a parameter arising from a
@@ -4408,11 +4622,31 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,
QualType T) {
ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, 0,
T, Context.getTrivialTypeSourceInfo(T, Loc),
- VarDecl::None, VarDecl::None, 0);
+ SC_None, SC_None, 0);
Param->setImplicit();
return Param;
}
+void Sema::DiagnoseUnusedParameters(ParmVarDecl * const *Param,
+ ParmVarDecl * const *ParamEnd) {
+ if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) ==
+ Diagnostic::Ignored)
+ return;
+
+ // Don't diagnose unused-parameter errors in template instantiations; we
+ // will already have done so in the template itself.
+ if (!ActiveTemplateInstantiations.empty())
+ return;
+
+ for (; Param != ParamEnd; ++Param) {
+ if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
+ !(*Param)->hasAttr<UnusedAttr>()) {
+ Diag((*Param)->getLocation(), diag::warn_unused_parameter)
+ << (*Param)->getDeclName();
+ }
+ }
+}
+
ParmVarDecl *Sema::CheckParameter(DeclContext *DC,
TypeSourceInfo *TSInfo, QualType T,
IdentifierInfo *Name,
@@ -4487,8 +4721,8 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
}
}
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
- Declarator &D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
+ Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
"Not a function declarator!");
@@ -4500,9 +4734,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
Scope *ParentScope = FnBodyScope->getParent();
- DeclPtrTy DP = HandleDeclarator(ParentScope, D,
- MultiTemplateParamsArg(*this),
- /*IsFunctionDefinition=*/true);
+ Decl *DP = HandleDeclarator(ParentScope, D,
+ MultiTemplateParamsArg(*this),
+ /*IsFunctionDefinition=*/true);
return ActOnStartOfFunctionDef(FnBodyScope, DP);
}
@@ -4550,7 +4784,7 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) {
return MissingPrototype;
}
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// Clear the last template instantiation error context.
LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
@@ -4558,11 +4792,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
return D;
FunctionDecl *FD = 0;
- if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(D.getAs<Decl>()))
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
FD = FunTmpl->getTemplatedDecl();
else
- FD = cast<FunctionDecl>(D.getAs<Decl>());
+ FD = cast<FunctionDecl>(D);
// Enter a new function scope
PushFunctionScope();
@@ -4627,15 +4860,15 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>() &&
- (!FD->getAttr<DLLExportAttr>())) {
- // dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+ DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+ if (DA && (!FD->getAttr<DLLExportAttr>())) {
+ // dllimport attribute cannot be directly applied to definition.
+ if (!DA->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
FD->setInvalidDecl();
- return DeclPtrTy::make(FD);
+ return FD;
}
// Visual C++ appears to not think this is an issue, so only issue
@@ -4646,10 +4879,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// emitted.
Diag(FD->getLocation(),
diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
- << FD->getNameAsCString() << "dllimport";
+ << FD->getName() << "dllimport";
}
}
- return DeclPtrTy::make(FD);
+ return FD;
}
/// \brief Given the set of return statements within a function body,
@@ -4668,9 +4901,11 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
/// FIXME: Employ a smarter algorithm that accounts for multiple return
/// statements and the lifetimes of the NRVO candidates. We should be able to
/// find a maximal set of NRVO variables.
-static void ComputeNRVO(Stmt *Body, ReturnStmt **Returns, unsigned NumReturns) {
+static void ComputeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
+ ReturnStmt **Returns = Scope->Returns.data();
+
const VarDecl *NRVOCandidate = 0;
- for (unsigned I = 0; I != NumReturns; ++I) {
+ for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
if (!Returns[I]->getNRVOCandidate())
return;
@@ -4684,15 +4919,12 @@ static void ComputeNRVO(Stmt *Body, ReturnStmt **Returns, unsigned NumReturns) {
const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
}
-Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
+Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
return ActOnFinishFunctionBody(D, move(BodyArg), false);
}
-Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
- bool IsInstantiation) {
- Decl *dcl = D.getAs<Decl>();
- Stmt *Body = BodyArg.takeAs<Stmt>();
-
+Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
+ bool IsInstantiation) {
FunctionDecl *FD = 0;
FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
if (FunTmpl)
@@ -4718,8 +4950,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
MarkVTableUsed(FD->getLocation(), Constructor->getParent());
- ComputeNRVO(Body, FunctionScopes.back()->Returns.data(),
- FunctionScopes.back()->Returns.size());
+ ComputeNRVO(Body, getCurFunction());
}
assert(FD == getCurFunctionDecl() && "Function parsing confused");
@@ -4730,15 +4961,15 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
if (!MD->isInvalidDecl())
DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
} else {
- Body->Destroy(Context);
- return DeclPtrTy();
+ return 0;
}
// Verify and clean out per-function state.
// Check goto/label use.
+ FunctionScopeInfo *CurFn = getCurFunction();
for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
- I = getLabelMap().begin(), E = getLabelMap().end(); I != E; ++I) {
+ I = CurFn->LabelMap.begin(), E = CurFn->LabelMap.end(); I != E; ++I) {
LabelStmt *L = I->second;
// Verify that we have no forward references left. If so, there was a goto
@@ -4754,8 +4985,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
// the function body so that they aren't leaked and that the AST is well
// formed.
if (Body == 0) {
- // The whole function wasn't parsed correctly, just delete this.
- L->Destroy(Context);
+ // The whole function wasn't parsed correctly.
continue;
}
@@ -4785,14 +5015,18 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
// Verify that that gotos and switch cases don't jump into scopes illegally.
// Verify that that gotos and switch cases don't jump into scopes illegally.
- if (FunctionNeedsScopeChecking() &&
+ if (getCurFunction()->NeedsScopeChecking() &&
!dcl->isInvalidDecl() &&
!hasAnyErrorsInThisFunction())
DiagnoseInvalidJumps(Body);
- if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
+ if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) {
+ if (!Destructor->getParent()->isDependentType())
+ CheckDestructor(Destructor);
+
MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
Destructor->getParent());
+ }
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for
@@ -4804,13 +5038,11 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
// enabled.
QualType ResultType;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(dcl)) {
- ResultType = FD->getResultType();
- }
- else {
+ AnalysisWarnings.IssueWarnings(WP, FD);
+ } else {
ObjCMethodDecl *MD = cast<ObjCMethodDecl>(dcl);
- ResultType = MD->getResultType();
+ AnalysisWarnings.IssueWarnings(WP, MD);
}
- AnalysisWarnings.IssueWarnings(WP, dcl);
}
assert(ExprTemporaries.empty() && "Leftover temporaries in function");
@@ -4826,8 +5058,8 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
// deletion in some later function.
if (getDiagnostics().hasErrorOccurred())
ExprTemporaries.clear();
-
- return D;
+
+ return dcl;
}
/// ImplicitlyDefineFunction - An undeclared identifier was used in a function
@@ -4873,8 +5105,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
DeclContext *PrevDC = CurContext;
CurContext = Context.getTranslationUnitDecl();
- FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D));
FD->setImplicit();
CurContext = PrevDC;
@@ -4902,9 +5133,17 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
+ if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
+ HasVAListArg)) {
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "scanf", FormatIdx+1,
+ HasVAListArg ? 0 : FormatIdx+2));
+ }
// Mark const if we don't care about errno and that is the only
// thing preventing the function from being const. This allows
@@ -4912,15 +5151,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
if (!getLangOptions().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
if (!FD->getAttr<ConstAttr>())
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
if (Context.BuiltinInfo.isNoReturn(BuiltinID))
FD->setType(Context.getNoReturnType(FD->getType()));
if (Context.BuiltinInfo.isNoThrow(BuiltinID))
- FD->addAttr(::new (Context) NoThrowAttr());
+ FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
if (Context.BuiltinInfo.isConst(BuiltinID))
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
IdentifierInfo *Name = FD->getIdentifier();
@@ -4942,13 +5181,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType(Context, "printf");
} else
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps?
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -5031,7 +5272,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
/// former case, Name will be non-null. In the later case, Name will be null.
/// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
/// reference/declaration/definition of a tag.
-Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr, AccessSpecifier AS,
@@ -5063,7 +5304,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// This is a declaration or definition of a class template (which may
// be a member of another template).
if (Invalid)
- return DeclPtrTy();
+ return 0;
OwnedDecl = false;
DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
@@ -5106,26 +5347,26 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, false);
if (!DC) {
IsDependent = true;
- return DeclPtrTy();
+ return 0;
}
} else {
DC = computeDeclContext(SS, true);
if (!DC) {
Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
<< SS.getRange();
- return DeclPtrTy();
+ return 0;
}
}
if (RequireCompleteDeclContext(SS, DC))
- return DeclPtrTy::make((Decl *)0);
+ return 0;
SearchDC = DC;
// Look-up name inside 'foo::'.
LookupQualifiedName(Previous, DC);
if (Previous.isAmbiguous())
- return DeclPtrTy();
+ return 0;
if (Previous.empty()) {
// Name lookup did not find anything. However, if the
@@ -5135,7 +5376,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// this as a dependent elaborated-type-specifier.
if (Previous.wasNotFoundInCurrentInstantiation()) {
IsDependent = true;
- return DeclPtrTy();
+ return 0;
}
// A tag 'foo::bar' must already exist.
@@ -5155,7 +5396,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Note: there used to be some attempt at recovery here.
if (Previous.isAmbiguous())
- return DeclPtrTy();
+ return 0;
if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
@@ -5176,7 +5417,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
- DC->Equals(StdNamespace) && Name->isStr("bad_alloc")) {
+ DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) {
// This is a declaration of or a reference to "std::bad_alloc".
isStdBadAlloc = true;
@@ -5184,7 +5425,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// std::bad_alloc has been implicitly declared (but made invisible to
// name lookup). Fill in this implicit declaration as the previous
// declaration, so that the declarations get chained appropriately.
- Previous.addDecl(StdBadAlloc);
+ Previous.addDecl(getStdBadAlloc());
}
}
@@ -5271,11 +5512,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
TagDecl *Tag = TT->getDecl();
if (Tag->getDeclName() == Name &&
- Tag->getDeclContext()->getLookupContext()
- ->Equals(TD->getDeclContext()->getLookupContext())) {
+ Tag->getDeclContext()->getRedeclContext()
+ ->Equals(TD->getDeclContext()->getRedeclContext())) {
PrevDecl = Tag;
Previous.clear();
Previous.addDecl(Tag);
+ Previous.resolveKind();
}
}
}
@@ -5321,7 +5563,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// need to be changed with DeclGroups.
if ((TUK == TUK_Reference && !PrevTagDecl->getFriendObjectKind()) ||
TUK == TUK_Friend)
- return DeclPtrTy::make(PrevTagDecl);
+ return PrevTagDecl;
// Diagnose attempts to redefine a tag.
if (TUK == TUK_Definition) {
@@ -5475,7 +5717,7 @@ CreateNewDecl:
New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
cast_or_null<CXXRecordDecl>(PrevDecl));
- if (isStdBadAlloc && (!StdBadAlloc || StdBadAlloc->isImplicit()))
+ if (isStdBadAlloc && (!StdBadAlloc || getStdBadAlloc()->isImplicit()))
StdBadAlloc = cast<CXXRecordDecl>(New);
} else
New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
@@ -5549,7 +5791,7 @@ CreateNewDecl:
if (PrevDecl)
New->setAccess(PrevDecl->getAccess());
- DeclContext *DC = New->getDeclContext()->getLookupContext();
+ DeclContext *DC = New->getDeclContext()->getRedeclContext();
DC->makeDeclVisibleInContext(New, /* Recoverable = */ false);
if (Name) // can be null along some error paths
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
@@ -5564,26 +5806,26 @@ CreateNewDecl:
// If this is the C FILE type, notify the AST context.
if (IdentifierInfo *II = New->getIdentifier())
if (!New->isInvalidDecl() &&
- New->getDeclContext()->getLookupContext()->isTranslationUnit() &&
+ New->getDeclContext()->getRedeclContext()->isTranslationUnit() &&
II->isStr("FILE"))
Context.setFILEDecl(New);
OwnedDecl = true;
- return DeclPtrTy::make(New);
+ return New;
}
-void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
+void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
AdjustDeclIfTemplate(TagD);
- TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+ TagDecl *Tag = cast<TagDecl>(TagD);
// Enter the tag context.
PushDeclContext(S, Tag);
}
-void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
+void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
SourceLocation LBraceLoc) {
AdjustDeclIfTemplate(TagD);
- CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD.getAs<Decl>());
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD);
FieldCollector->StartClass();
@@ -5610,10 +5852,10 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
"Broken injected-class-name");
}
-void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
+void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
SourceLocation RBraceLoc) {
AdjustDeclIfTemplate(TagD);
- TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+ TagDecl *Tag = cast<TagDecl>(TagD);
Tag->setRBraceLoc(RBraceLoc);
if (isa<CXXRecordDecl>(Tag))
@@ -5626,9 +5868,9 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
Consumer.HandleTagDeclDefinition(Tag);
}
-void Sema::ActOnTagDefinitionError(Scope *S, DeclPtrTy TagD) {
+void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
AdjustDeclIfTemplate(TagD);
- TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+ TagDecl *Tag = cast<TagDecl>(TagD);
Tag->setInvalidDecl();
// We're undoing ActOnTagStartDefinition here, not
@@ -5711,13 +5953,13 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
/// ActOnField - Each field of a struct/union/class is passed into this in order
/// to create a FieldDecl object for it.
-Sema::DeclPtrTy Sema::ActOnField(Scope *S, DeclPtrTy TagD,
+Decl *Sema::ActOnField(Scope *S, Decl *TagD,
SourceLocation DeclStart,
Declarator &D, ExprTy *BitfieldWidth) {
- FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD.getAs<Decl>()),
+ FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD),
DeclStart, D, static_cast<Expr*>(BitfieldWidth),
AS_public);
- return DeclPtrTy::make(Res);
+ return Res;
}
/// HandleField - Analyze a field of a C struct or a C++ data member.
@@ -5739,9 +5981,17 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+
+ // Check to see if this name was declared as a member previously
+ LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
+ LookupName(Previous, S);
+ assert((Previous.empty() || Previous.isOverloadedResult() ||
+ Previous.isSingleResult())
+ && "Lookup of member name should be either overloaded, single or null");
- NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,
- ForRedeclaration);
+ // If the name is overloaded then get any declaration else get the single result
+ NamedDecl *PrevDecl = Previous.isOverloadedResult() ?
+ Previous.getRepresentativeDecl() : Previous.getAsSingle<NamedDecl>();
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
@@ -5804,21 +6054,29 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
QualType EltTy = Context.getBaseElementType(T);
if (!EltTy->isDependentType() &&
- RequireCompleteType(Loc, EltTy, diag::err_field_incomplete))
+ RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
+ // Fields of incomplete type force their record to be invalid.
+ Record->setInvalidDecl();
InvalidDecl = true;
+ }
// C99 6.7.2.1p8: A member of a structure or union may have any type other
// than a variably modified type.
if (!InvalidDecl && T->isVariablyModifiedType()) {
bool SizeIsNegative;
+ llvm::APSInt Oversized;
QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
- SizeIsNegative);
+ SizeIsNegative,
+ Oversized);
if (!FixedTy.isNull()) {
Diag(Loc, diag::warn_illegal_constant_array_size);
T = FixedTy;
} else {
if (SizeIsNegative)
Diag(Loc, diag::err_typecheck_negative_array_size);
+ else if (Oversized.getBoolValue())
+ Diag(Loc, diag::err_array_too_large)
+ << Oversized.toString(10);
else
Diag(Loc, diag::err_typecheck_field_variable_size);
InvalidDecl = true;
@@ -5836,7 +6094,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
if (!InvalidDecl && BitWidth &&
VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) {
InvalidDecl = true;
- DeleteExpr(BitWidth);
BitWidth = 0;
ZeroWidth = false;
}
@@ -5877,6 +6134,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
CXXRecord->setPOD(false);
if (!ZeroWidth)
CXXRecord->setEmpty(false);
+ if (T->isReferenceType())
+ CXXRecord->setHasTrivialConstructor(false);
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
@@ -5896,27 +6155,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
// cannot be a member of a union, nor can an array of such
// objects.
// TODO: C++0x alters this restriction significantly.
- if (Record->isUnion()) {
- // We check for copy constructors before constructors
- // because otherwise we'll never get complaints about
- // copy constructors.
-
- CXXSpecialMember member = CXXInvalid;
- if (!RDecl->hasTrivialCopyConstructor())
- member = CXXCopyConstructor;
- else if (!RDecl->hasTrivialConstructor())
- member = CXXConstructor;
- else if (!RDecl->hasTrivialCopyAssignment())
- member = CXXCopyAssignment;
- else if (!RDecl->hasTrivialDestructor())
- member = CXXDestructor;
-
- if (member != CXXInvalid) {
- Diag(Loc, diag::err_illegal_union_member) << Name << member;
- DiagnoseNontrivial(RT, member);
- NewFD->setInvalidDecl();
- }
- }
+ if (Record->isUnion() && CheckNontrivialField(NewFD))
+ NewFD->setInvalidDecl();
}
}
}
@@ -5946,6 +6186,43 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
return NewFD;
}
+bool Sema::CheckNontrivialField(FieldDecl *FD) {
+ assert(FD);
+ assert(getLangOptions().CPlusPlus && "valid check only for C++");
+
+ if (FD->isInvalidDecl())
+ return true;
+
+ QualType EltTy = Context.getBaseElementType(FD->getType());
+ if (const RecordType *RT = EltTy->getAs<RecordType>()) {
+ CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+ if (RDecl->getDefinition()) {
+ // We check for copy constructors before constructors
+ // because otherwise we'll never get complaints about
+ // copy constructors.
+
+ CXXSpecialMember member = CXXInvalid;
+ if (!RDecl->hasTrivialCopyConstructor())
+ member = CXXCopyConstructor;
+ else if (!RDecl->hasTrivialConstructor())
+ member = CXXConstructor;
+ else if (!RDecl->hasTrivialCopyAssignment())
+ member = CXXCopyAssignment;
+ else if (!RDecl->hasTrivialDestructor())
+ member = CXXDestructor;
+
+ if (member != CXXInvalid) {
+ Diag(FD->getLocation(), diag::err_illegal_union_or_anon_struct_member)
+ << (int)FD->getParent()->isUnion() << FD->getDeclName() << member;
+ DiagnoseNontrivial(RT, member);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
/// DiagnoseNontrivial - Given that a class has a non-trivial
/// special member, figure out why.
void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
@@ -6091,9 +6368,9 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) {
/// ActOnIvar - Each ivar field of an objective-c class is passed into this
/// in order to create an IvarDecl object for it.
-Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
+Decl *Sema::ActOnIvar(Scope *S,
SourceLocation DeclStart,
- DeclPtrTy IntfDecl,
+ Decl *IntfDecl,
Declarator &D, ExprTy *BitfieldWidth,
tok::ObjCKeywordKind Visibility) {
@@ -6112,7 +6389,6 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
// 6.7.2.1p3, 6.7.2.1p4
if (VerifyBitField(Loc, II, T, BitWidth)) {
D.setInvalidType();
- DeleteExpr(BitWidth);
BitWidth = 0;
}
} else {
@@ -6137,19 +6413,23 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
: ObjCIvarDecl::None;
// Must set ivar's DeclContext to its enclosing interface.
- ObjCContainerDecl *EnclosingDecl = IntfDecl.getAs<ObjCContainerDecl>();
+ ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(IntfDecl);
ObjCContainerDecl *EnclosingContext;
if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
+ if (!LangOpts.ObjCNonFragileABI2) {
// Case of ivar declared in an implementation. Context is that of its class.
- EnclosingContext = IMPDecl->getClassInterface();
- assert(EnclosingContext && "Implementation has no class interface!");
+ EnclosingContext = IMPDecl->getClassInterface();
+ assert(EnclosingContext && "Implementation has no class interface!");
+ }
+ else
+ EnclosingContext = EnclosingDecl;
} else {
if (ObjCCategoryDecl *CDecl =
dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) {
Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
- return DeclPtrTy();
+ return 0;
}
}
EnclosingContext = EnclosingDecl;
@@ -6180,19 +6460,59 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
if (II) {
// FIXME: When interfaces are DeclContexts, we'll need to add
// these to the interface.
- S->AddDecl(DeclPtrTy::make(NewID));
+ S->AddDecl(NewID);
IdResolver.AddDecl(NewID);
}
- return DeclPtrTy::make(NewID);
+ return NewID;
+}
+
+/// ActOnLastBitfield - This routine handles synthesized bitfields rules for
+/// class and class extensions. For every class @interface and class
+/// extension @interface, if the last ivar is a bitfield of any type,
+/// then add an implicit `char :0` ivar to the end of that interface.
+void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl,
+ llvm::SmallVectorImpl<Decl *> &AllIvarDecls) {
+ if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty())
+ return;
+
+ Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
+ ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
+
+ if (!Ivar->isBitField())
+ return;
+ uint64_t BitFieldSize =
+ Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+ if (BitFieldSize == 0)
+ return;
+ ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl);
+ if (!ID) {
+ if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+ if (!CD->IsClassExtension())
+ return;
+ }
+ // No need to add this to end of @implementation.
+ else
+ return;
+ }
+ // All conditions are met. Add a new bitfield to the tail end of ivars.
+ llvm::APInt Zero(Context.getTypeSize(Context.CharTy), 0);
+ Expr * BW = IntegerLiteral::Create(Context, Zero, Context.CharTy, DeclLoc);
+
+ Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
+ DeclLoc, 0,
+ Context.CharTy,
+ Context.CreateTypeSourceInfo(Context.CharTy),
+ ObjCIvarDecl::Private, BW,
+ true);
+ AllIvarDecls.push_back(Ivar);
}
void Sema::ActOnFields(Scope* S,
- SourceLocation RecLoc, DeclPtrTy RecDecl,
- DeclPtrTy *Fields, unsigned NumFields,
+ SourceLocation RecLoc, Decl *EnclosingDecl,
+ Decl **Fields, unsigned NumFields,
SourceLocation LBrac, SourceLocation RBrac,
AttributeList *Attr) {
- Decl *EnclosingDecl = RecDecl.getAs<Decl>();
assert(EnclosingDecl && "missing record or interface decl");
// If the decl this is being inserted into is invalid, then it may be a
@@ -6209,7 +6529,7 @@ void Sema::ActOnFields(Scope* S,
RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
for (unsigned i = 0; i != NumFields; ++i) {
- FieldDecl *FD = cast<FieldDecl>(Fields[i].getAs<Decl>());
+ FieldDecl *FD = cast<FieldDecl>(Fields[i]);
// Get the type for the field.
Type *FDTy = FD->getType().getTypePtr();
@@ -6244,7 +6564,7 @@ void Sema::ActOnFields(Scope* S,
EnclosingDecl->setInvalidDecl();
continue;
} else if (FDTy->isIncompleteArrayType() && i == NumFields - 1 &&
- Record && Record->isStruct()) {
+ Record && !Record->isUnion()) {
// Flexible array member.
if (NumNamedMembers < 1) {
Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
@@ -6360,6 +6680,11 @@ void Sema::ActOnFields(Scope* S,
if (Attr)
ProcessDeclAttributeList(S, Record, Attr);
+
+ // If there's a #pragma GCC visibility in scope, and this isn't a subclass,
+ // set the visibility of this record.
+ if (Record && !Record->getDeclContext()->isRecord())
+ AddPushedVisibilityAttribute(Record);
}
/// \brief Determine whether the given integral value is representable within
@@ -6405,9 +6730,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
EnumConstantDecl *LastEnumConst,
SourceLocation IdLoc,
IdentifierInfo *Id,
- ExprArg val) {
- Expr *Val = (Expr *)val.get();
-
+ Expr *Val) {
unsigned IntWidth = Context.Target.getIntWidth();
llvm::APSInt EnumVal(IntWidth);
QualType EltTy;
@@ -6434,12 +6757,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
<< (EnumVal.isUnsigned() || EnumVal.isNonNegative());
else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
// Force the type of the expression to 'int'.
- ImpCastExprToType(Val, Context.IntTy, CastExpr::CK_IntegralCast);
-
- if (Val != val.get()) {
- val.release();
- val = Val;
- }
+ ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast);
}
}
@@ -6527,20 +6845,19 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
EnumVal.setIsSigned(EltTy->isSignedIntegerType());
}
- val.release();
return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy,
Val, EnumVal);
}
-Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
- DeclPtrTy lastEnumConst,
+Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl,
+ Decl *lastEnumConst,
SourceLocation IdLoc,
IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *val) {
- EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl.getAs<Decl>());
+ EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);
EnumConstantDecl *LastEnumConst =
- cast_or_null<EnumConstantDecl>(lastEnumConst.getAs<Decl>());
+ cast_or_null<EnumConstantDecl>(lastEnumConst);
Expr *Val = static_cast<Expr*>(val);
// The scope passed in may not be a decl scope. Zip up the scope tree until
@@ -6569,13 +6886,12 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
else
Diag(IdLoc, diag::err_redefinition) << Id;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- if (Val) Val->Destroy(Context);
- return DeclPtrTy();
+ return 0;
}
}
EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
- IdLoc, Id, Owned(Val));
+ IdLoc, Id, Val);
// Register this decl in the current scope stack.
if (New) {
@@ -6583,14 +6899,14 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
PushOnScopeChains(New, S);
}
- return DeclPtrTy::make(New);
+ return New;
}
void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
- SourceLocation RBraceLoc, DeclPtrTy EnumDeclX,
- DeclPtrTy *Elements, unsigned NumElements,
+ SourceLocation RBraceLoc, Decl *EnumDeclX,
+ Decl **Elements, unsigned NumElements,
Scope *S, AttributeList *Attr) {
- EnumDecl *Enum = cast<EnumDecl>(EnumDeclX.getAs<Decl>());
+ EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
QualType EnumType = Context.getTypeDeclType(Enum);
if (Attr)
@@ -6599,7 +6915,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
if (Enum->isDependentType()) {
for (unsigned i = 0; i != NumElements; ++i) {
EnumConstantDecl *ECD =
- cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+ cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue;
ECD->setType(EnumType);
@@ -6626,7 +6942,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
for (unsigned i = 0; i != NumElements; ++i) {
EnumConstantDecl *ECD =
- cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+ cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue; // Already issued a diagnostic.
const llvm::APSInt &InitVal = ECD->getInitVal();
@@ -6728,8 +7044,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// Loop over all of the enumerator constants, changing their types to match
// the type of the enum if needed.
for (unsigned i = 0; i != NumElements; ++i) {
- EnumConstantDecl *ECD =
- cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+ EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue; // Already issued a diagnostic.
// Standard C says the enumerators have int type, but we allow, as an
@@ -6772,11 +7087,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// Adjust the Expr initializer and type.
if (ECD->getInitExpr())
- ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy,
- CastExpr::CK_IntegralCast,
- ECD->getInitExpr(),
- CXXBaseSpecifierArray(),
- /*isLvalue=*/false));
+ ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
+ CK_IntegralCast,
+ ECD->getInitExpr(),
+ /*base paths*/ 0,
+ VK_RValue));
if (getLangOptions().CPlusPlus)
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
@@ -6790,14 +7105,13 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
NumPositiveBits, NumNegativeBits);
}
-Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
- ExprArg expr) {
- StringLiteral *AsmString = cast<StringLiteral>(expr.takeAs<Expr>());
+Decl *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr) {
+ StringLiteral *AsmString = cast<StringLiteral>(expr);
FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
Loc, AsmString);
CurContext->addDecl(New);
- return DeclPtrTy::make(New);
+ return New;
}
void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
@@ -6806,7 +7120,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
} else {
(void)WeakUndeclaredIdentifiers.insert(
std::pair<IdentifierInfo*,WeakInfo>
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3b82f58be43e..25af73ae13d3 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -11,15 +11,18 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
#include "TargetAttributesSema.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/DelayedDiagnostic.h"
#include "llvm/ADT/StringExtras.h"
using namespace clang;
+using namespace sema;
//===----------------------------------------------------------------------===//
// Helper functions
@@ -193,7 +196,7 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
// Instantiate/Install the vector type, and let Sema build the type for us.
// This will run the reguired checks.
- QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
+ QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
if (!T.isNull()) {
// FIXME: preserve the old source info.
tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
@@ -211,7 +214,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(::new (S.Context) PackedAttr);
+ TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
// If the alignment is less than or equal to 8 bits, the packed attribute
// has no effect.
@@ -220,7 +223,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(::new (S.Context) PackedAttr);
+ FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -235,7 +238,7 @@ static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
// The IBAction attributes only apply to instance methods.
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
if (MD->isInstanceMethod()) {
- d->addAttr(::new (S.Context) IBActionAttr());
+ d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
return;
}
@@ -252,7 +255,7 @@ static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
// The IBOutlet attributes only apply to instance variables of
// Objective-C classes.
if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
- d->addAttr(::new (S.Context) IBOutletAttr());
+ d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
return;
}
@@ -263,7 +266,7 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
Sema &S) {
// The iboutletcollection attribute can have zero or one arguments.
- if (Attr.getNumArgs() > 1) {
+ if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
}
@@ -274,9 +277,41 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
return;
}
-
- // FIXME: Eventually accept the type argument.
- d->addAttr(::new (S.Context) IBOutletCollectionAttr());
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
+ if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
+ S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
+ << VD->getType() << 0;
+ return;
+ }
+ if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
+ if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
+ S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
+ << PD->getType() << 1;
+ return;
+ }
+
+ IdentifierInfo *II = Attr.getParameterName();
+ if (!II)
+ II = &S.Context.Idents.get("id");
+
+ ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
+ S.getScopeForContext(d->getDeclContext()->getParent()));
+ if (!TypeRep) {
+ S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+ return;
+ }
+ QualType QT = TypeRep.get();
+ // Diagnose use of non-object type in iboutletcollection attribute.
+ // FIXME. Gnu attribute extension ignores use of builtin types in
+ // attributes. So, __attribute__((iboutletcollection(char))) will be
+ // treated as __attribute__((iboutletcollection())).
+ if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
+ !QT->isObjCObjectType()) {
+ S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+ return;
+ }
+ d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+ QT));
}
static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -321,7 +356,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
QualType T = getFunctionOrMethodArgType(d, x);
if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
// FIXME: Should also highlight argument in decl.
- S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
+ S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
<< "nonnull" << Ex->getSourceRange();
continue;
}
@@ -346,15 +381,162 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
- std::sort(start, start + size);
- d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+ llvm::array_pod_sort(start, start + size);
+ d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+ size));
+}
+
+static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
+ // This attribute must be applied to a function declaration.
+ // The first argument to the attribute must be a string,
+ // the name of the resource, for example "malloc".
+ // The following arguments must be argument indexes, the arguments must be
+ // of integer type for Returns, otherwise of pointer type.
+ // The difference between Holds and Takes is that a pointer may still be used
+ // after being held. free() should be __attribute((ownership_takes)), whereas
+ // a list append function may well be __attribute((ownership_holds)).
+
+ if (!AL.getParameterName()) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
+ << AL.getName()->getName() << 1;
+ return;
+ }
+ // Figure out our Kind, and check arguments while we're at it.
+ OwnershipAttr::OwnershipKind K;
+ switch (AL.getKind()) {
+ case AttributeList::AT_ownership_takes:
+ K = OwnershipAttr::Takes;
+ if (AL.getNumArgs() < 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+ return;
+ }
+ break;
+ case AttributeList::AT_ownership_holds:
+ K = OwnershipAttr::Holds;
+ if (AL.getNumArgs() < 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+ return;
+ }
+ break;
+ case AttributeList::AT_ownership_returns:
+ K = OwnershipAttr::Returns;
+ if (AL.getNumArgs() > 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
+ << AL.getNumArgs() + 1;
+ return;
+ }
+ break;
+ default:
+ // This should never happen given how we are called.
+ llvm_unreachable("Unknown ownership attribute");
+ }
+
+ if (!isFunction(d) || !hasFunctionProto(d)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
+ << 0 /*function*/;
+ return;
+ }
+
+ unsigned NumArgs = getFunctionOrMethodNumArgs(d);
+
+ llvm::StringRef Module = AL.getParameterName()->getName();
+
+ // Normalize the argument, __foo__ becomes foo.
+ if (Module.startswith("__") && Module.endswith("__"))
+ Module = Module.substr(2, Module.size() - 4);
+
+ llvm::SmallVector<unsigned, 10> OwnershipArgs;
+
+ for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
+ ++I) {
+
+ Expr *IdxExpr = static_cast<Expr *>(*I);
+ llvm::APSInt ArgNum(32);
+ if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+ || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
+ << AL.getName()->getName() << IdxExpr->getSourceRange();
+ continue;
+ }
+
+ unsigned x = (unsigned) ArgNum.getZExtValue();
+
+ if (x > NumArgs || x < 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << AL.getName()->getName() << x << IdxExpr->getSourceRange();
+ continue;
+ }
+ --x;
+ switch (K) {
+ case OwnershipAttr::Takes:
+ case OwnershipAttr::Holds: {
+ // Is the function argument a pointer type?
+ QualType T = getFunctionOrMethodArgType(d, x);
+ if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
+ // FIXME: Should also highlight argument in decl.
+ S.Diag(AL.getLoc(), diag::err_ownership_type)
+ << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
+ << "pointer"
+ << IdxExpr->getSourceRange();
+ continue;
+ }
+ break;
+ }
+ case OwnershipAttr::Returns: {
+ if (AL.getNumArgs() > 1) {
+ // Is the function argument an integer type?
+ Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
+ llvm::APSInt ArgNum(32);
+ if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+ || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+ S.Diag(AL.getLoc(), diag::err_ownership_type)
+ << "ownership_returns" << "integer"
+ << IdxExpr->getSourceRange();
+ return;
+ }
+ }
+ break;
+ }
+ default:
+ llvm_unreachable("Unknown ownership attribute");
+ } // switch
+
+ // Check we don't have a conflict with another ownership attribute.
+ for (specific_attr_iterator<OwnershipAttr>
+ i = d->specific_attr_begin<OwnershipAttr>(),
+ e = d->specific_attr_end<OwnershipAttr>();
+ i != e; ++i) {
+ if ((*i)->getOwnKind() != K) {
+ for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
+ I!=E; ++I) {
+ if (x == *I) {
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+ << AL.getName()->getName() << "ownership_*";
+ }
+ }
+ }
+ }
+ OwnershipArgs.push_back(x);
+ }
+
+ unsigned* start = OwnershipArgs.data();
+ unsigned size = OwnershipArgs.size();
+ llvm::array_pod_sort(start, start + size);
+
+ if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+ return;
+ }
+
+ d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+ start, size));
}
static bool isStaticVarOrStaticFunciton(Decl *D) {
if (VarDecl *VD = dyn_cast<VarDecl>(D))
- return VD->getStorageClass() == VarDecl::Static;
+ return VD->getStorageClass() == SC_Static;
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return FD->getStorageClass() == FunctionDecl::Static;
+ return FD->getStorageClass() == SC_Static;
return false;
}
@@ -375,13 +557,11 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// static int a __attribute__((weakref ("v2")));
// }
// we reject them
- if (const DeclContext *Ctx = d->getDeclContext()) {
- Ctx = Ctx->getLookupContext();
- if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) {
- S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
- dyn_cast<NamedDecl>(d)->getNameAsString();
- return;
- }
+ const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
+ if (!Ctx->isFileContext()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
+ dyn_cast<NamedDecl>(d)->getNameAsString();
+ return;
}
// The GCC manual says
@@ -424,10 +604,10 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
- d->addAttr(::new (S.Context) WeakRefAttr());
+ d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -449,7 +629,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: check if target symbol exists in current file
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -466,7 +646,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
return;
}
- d->addAttr(::new (S.Context) AlwaysInlineAttr());
+ d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -479,7 +659,7 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
QualType RetTy = FD->getResultType();
if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
- d->addAttr(::new (S.Context) MallocAttr());
+ d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
return;
}
}
@@ -487,39 +667,75 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
}
-static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
- // check the attribute arguments.
+static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
+ assert(Attr.isInvalid() == false);
+ d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+ Sema &S) {
+
+ // The checking path for 'noreturn' and 'analyzer_noreturn' are different
+ // because 'analyzer_noreturn' does not impact the type.
+
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
- return false;
+ return;
}
-
+
if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
ValueDecl *VD = dyn_cast<ValueDecl>(d);
if (VD == 0 || (!VD->getType()->isBlockPointerType()
&& !VD->getType()->isFunctionPointerType())) {
S.Diag(Attr.getLoc(),
Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
- : diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << 0 /*function*/;
- return false;
+ : diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 0 /*function*/;
+ return;
}
}
-
- return true;
-}
-
-static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
- /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
- assert(Attr.isInvalid() == false);
- d->addAttr(::new (S.Context) NoReturnAttr());
+
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
}
-static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+// PS3 PPU-specific.
+static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
- if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+/*
+ Returning a Vector Class in Registers
+
+ According to the PPU ABI specifications, a class with a single member of vector type is returned in
+ memory when used as the return value of a function. This results in inefficient code when implementing
+ vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
+ definition. This attribute is also applicable to struct types.
+
+ Example:
+
+ struct Vector
+ {
+ __vector float xyzw;
+ } __attribute__((vecreturn));
+
+ Vector Add(Vector lhs, Vector rhs)
+ {
+ Vector result;
+ result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+ return result; // This will be returned in a register
+ }
+*/
+ if (!isa<CXXRecordDecl>(d)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << 9 /*class*/;
+ return;
+ }
+
+ if (d->getAttr<VecReturnAttr>()) {
+ S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+ return;
+ }
+
+ d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}
static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -545,7 +761,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) UnusedAttr());
+ d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
}
static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -566,7 +782,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -596,7 +812,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) ConstructorAttr(priority));
+ d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -626,7 +842,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) DestructorAttr(priority));
+ d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -636,7 +852,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) DeprecatedAttr());
+ d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -646,7 +862,7 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) UnavailableAttr());
+ d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
}
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -667,22 +883,22 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
llvm::StringRef TypeStr = Str->getString();
- VisibilityAttr::VisibilityTypes type;
+ VisibilityAttr::VisibilityType type;
if (TypeStr == "default")
- type = VisibilityAttr::DefaultVisibility;
+ type = VisibilityAttr::Default;
else if (TypeStr == "hidden")
- type = VisibilityAttr::HiddenVisibility;
+ type = VisibilityAttr::Hidden;
else if (TypeStr == "internal")
- type = VisibilityAttr::HiddenVisibility; // FIXME
+ type = VisibilityAttr::Hidden; // FIXME
else if (TypeStr == "protected")
- type = VisibilityAttr::ProtectedVisibility;
+ type = VisibilityAttr::Protected;
else {
S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
return;
}
- d->addAttr(::new (S.Context) VisibilityAttr(type));
+ d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
}
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -698,7 +914,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
return;
}
- D->addAttr(::new (S.Context) ObjCExceptionAttr());
+ D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
}
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -714,7 +930,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
}
- D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+ D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
}
static void
@@ -729,7 +945,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) OverloadableAttr());
+ D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
}
static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -744,7 +960,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- BlocksAttr::BlocksAttrTypes type;
+ BlocksAttr::BlockType type;
if (Attr.getParameterName()->isStr("byref"))
type = BlocksAttr::ByRef;
else {
@@ -753,7 +969,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) BlocksAttr(type));
+ d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
}
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -846,7 +1062,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
<< Attr.getName() << 6 /*function, method or block */;
return;
}
- d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+ d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
}
static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -874,7 +1090,7 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
return;
}
- D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+ D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -898,7 +1114,7 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) WeakAttr());
+ D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -934,7 +1150,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) WeakImportAttr());
+ D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
}
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -957,7 +1173,8 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
}
WGSize[i] = (unsigned) ArgNum.getZExtValue();
}
- D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+ D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+ WGSize[0], WGSize[1],
WGSize[2]));
}
@@ -991,7 +1208,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+ D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
}
@@ -1002,7 +1219,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) NoThrowAttr());
+ d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
}
static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1012,7 +1229,7 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) ConstAttr());
+ d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
}
static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1022,7 +1239,7 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) PureAttr());
+ d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
}
static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1080,7 +1297,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) CleanupAttr(FD));
+ d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1143,7 +1360,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+ d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
}
enum FormatAttrKind {
@@ -1225,7 +1442,7 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
Attr.setInvalid();
return;
}
- d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+ d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -1369,7 +1586,8 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+ d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+ Idx.getZExtValue(),
FirstArg.getZExtValue()));
}
@@ -1438,7 +1656,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
}
}
- RD->addAttr(::new (S.Context) TransparentUnionAttr());
+ RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
}
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1456,7 +1674,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
- d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+ d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
}
static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1471,9 +1689,7 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// weaker alignment, rather than being silently ignored.
if (Attr.getNumArgs() == 0) {
- // FIXME: This should be the target specific maximum alignment.
- // (For now we just use 128 bits which is the maximum on X86).
- D->addAttr(::new (S.Context) AlignedAttr(128));
+ D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
return;
}
@@ -1483,10 +1699,11 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
if (E->isTypeDependent() || E->isValueDependent()) {
// Save dependent expressions in the AST to be instantiated.
- D->addAttr(::new (Context) AlignedAttr(E));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
return;
}
+ // FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
if (!E->isIntegerConstantExpr(Alignment, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_not_int)
@@ -1499,7 +1716,14 @@ void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
return;
}
- D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+ // FIXME: Cache the number on the Attr object if non-dependent?
+ // FIXME: Perform checking of type validity
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+ return;
}
/// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1686,7 +1910,7 @@ static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) NoDebugAttr());
+ d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1702,7 +1926,7 @@ static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) NoInlineAttr());
+ d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
@@ -1719,7 +1943,7 @@ static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
return;
}
- d->addAttr(::new (S.Context) NoInstrumentFunctionAttr());
+ d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
}
static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1741,7 +1965,7 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) GNUInlineAttr());
+ d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1751,15 +1975,19 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
switch (Attr.getKind()) {
case AttributeList::AT_fastcall:
- d->addAttr(::new (S.Context) FastCallAttr());
+ d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_stdcall:
- d->addAttr(::new (S.Context) StdCallAttr());
+ d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_thiscall:
- d->addAttr(::new (S.Context) ThisCallAttr());
+ d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
+ return;
case AttributeList::AT_cdecl:
- d->addAttr(::new (S.Context) CDeclAttr());
+ d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
+ return;
+ case AttributeList::AT_pascal:
+ d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
return;
default:
llvm_unreachable("unexpected attribute kind");
@@ -1801,7 +2029,8 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+ d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+ NumParams.getZExtValue()));
}
static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1827,7 +2056,7 @@ static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) FinalAttr());
+ d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -1853,7 +2082,7 @@ static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) BaseCheckAttr());
+ d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
}
static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1878,7 +2107,7 @@ static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) HidingAttr());
+ d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
}
static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1903,7 +2132,7 @@ static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(::new (S.Context) OverrideAttr());
+ d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -1939,16 +2168,16 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_cf_returns_not_retained:
- d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_not_retained:
- d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
};
}
@@ -2009,9 +2238,14 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
+ case AttributeList::AT_ownership_returns:
+ case AttributeList::AT_ownership_takes:
+ case AttributeList::AT_ownership_holds:
+ HandleOwnershipAttr (D, Attr, S); break;
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break;
+ case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break;
// Checker-specific.
case AttributeList::AT_ns_returns_not_retained:
@@ -2063,6 +2297,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
case AttributeList::AT_cdecl:
case AttributeList::AT_fastcall:
case AttributeList::AT_thiscall:
+ case AttributeList::AT_pascal:
HandleCallConvAttr(D, Attr, S);
break;
default:
@@ -2087,7 +2322,7 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *Attr
// but that looks really pointless. We reject it.
if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
- dyn_cast<NamedDecl>(D)->getNameAsString();
+ dyn_cast<NamedDecl>(D)->getNameAsString();
return;
}
}
@@ -2127,8 +2362,9 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
IdentifierInfo *NDId = ND->getIdentifier();
NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
- NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
- NewD->addAttr(::new (Context) WeakAttr());
+ NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+ NDId->getName()));
+ NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
WeakTopLevelDecl.push_back(NewD);
// FIXME: "hideous" code from Sema::LazilyCreateBuiltin
// to insert Decl at TU scope, sorry.
@@ -2137,7 +2373,7 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
PushOnScopeChains(NewD, S);
CurContext = SavedContext;
} else { // just add weak to existing
- ND->addAttr(::new (Context) WeakAttr());
+ ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
}
}
@@ -2179,12 +2415,12 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
///
/// The state token we use is the start index of this scope
/// on the warning stack.
-Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
+Sema::ParsingDeclStackState Sema::PushParsingDeclaration() {
ParsingDeclDepth++;
return (ParsingDeclStackState) DelayedDiagnostics.size();
}
-void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
+void Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
ParsingDeclDepth--;
@@ -2199,7 +2435,6 @@ void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
// We only want to actually emit delayed diagnostics when we
// successfully parsed a decl.
- Decl *D = Ctx ? Ctx.getAs<Decl>() : 0;
if (D) {
// We really do want to start with 0 here. We get one push for a
// decl spec and another for each declarator; in a decl group like:
@@ -2238,7 +2473,7 @@ static bool isDeclDeprecated(Decl *D) {
return false;
}
-void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
+void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
Decl *Ctx) {
if (isDeclDeprecated(Ctx))
return;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index bd97df2ce9d1..63acdb5f1cc6 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -11,9 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
@@ -23,10 +25,11 @@
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include <map>
#include <set>
@@ -108,7 +111,7 @@ namespace {
}
bool
-Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
SourceLocation EqualLoc) {
if (RequireCompleteType(Param->getLocation(), Param->getType(),
diag::err_typecheck_decl_incomplete_type)) {
@@ -116,8 +119,6 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
return true;
}
- Expr *Arg = (Expr *)DefaultArg.get();
-
// C++ [dcl.fct.default]p5
// A default argument expression is implicitly converted (clause
// 4) to the parameter type. The default argument expression has
@@ -128,8 +129,8 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(),
EqualLoc);
InitializationSequence InitSeq(*this, Entity, Kind, &Arg, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&Arg, 1));
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &Arg, 1));
if (Result.isInvalid())
return true;
Arg = Result.takeAs<Expr>();
@@ -139,8 +140,6 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
// Okay: add the default argument to the parameter
Param->setDefaultArg(Arg);
- DefaultArg.release();
-
return false;
}
@@ -148,16 +147,14 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
/// provided for a function parameter is well-formed. If so, attach it
/// to the parameter declaration.
void
-Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
- ExprArg defarg) {
- if (!param || !defarg.get())
+Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc,
+ Expr *DefaultArg) {
+ if (!param || !DefaultArg)
return;
- ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+ ParmVarDecl *Param = cast<ParmVarDecl>(param);
UnparsedDefaultArgLocs.erase(Param);
- ExprOwningPtr<Expr> DefaultArg(this, defarg.takeAs<Expr>());
-
// Default arguments are only permitted in C++
if (!getLangOptions().CPlusPlus) {
Diag(EqualLoc, diag::err_param_default_argument)
@@ -167,26 +164,26 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
}
// Check that the default argument is well-formed
- CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
- if (DefaultArgChecker.Visit(DefaultArg.get())) {
+ CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this);
+ if (DefaultArgChecker.Visit(DefaultArg)) {
Param->setInvalidDecl();
return;
}
- SetParamDefaultArgument(Param, move(DefaultArg), EqualLoc);
+ SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
}
/// ActOnParamUnparsedDefaultArgument - We've seen a default
/// argument for a function parameter, but we can't parse it yet
/// because we're inside a class definition. Note that this default
/// argument will be parsed later.
-void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+void Sema::ActOnParamUnparsedDefaultArgument(Decl *param,
SourceLocation EqualLoc,
SourceLocation ArgLoc) {
if (!param)
return;
- ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+ ParmVarDecl *Param = cast<ParmVarDecl>(param);
if (Param)
Param->setUnparsedDefaultArg();
@@ -195,11 +192,11 @@ void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
/// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
/// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param) {
if (!param)
return;
- ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+ ParmVarDecl *Param = cast<ParmVarDecl>(param);
Param->setInvalidDecl();
@@ -224,7 +221,7 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
if (chunk.Kind == DeclaratorChunk::Function) {
for (unsigned argIdx = 0, e = chunk.Fun.NumArgs; argIdx != e; ++argIdx) {
ParmVarDecl *Param =
- cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param.getAs<Decl>());
+ cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param);
if (Param->hasUnparsedDefaultArg()) {
CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens;
Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
@@ -412,8 +409,6 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
for (p = 0; p <= LastMissingDefaultArg; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
if (Param->hasDefaultArg()) {
- if (!Param->hasUnparsedDefaultArg())
- Param->getDefaultArg()->Destroy(Context);
Param->setDefaultArg(0);
}
}
@@ -449,8 +444,9 @@ CXXBaseSpecifier *
Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
- QualType BaseType,
- SourceLocation BaseLoc) {
+ TypeSourceInfo *TInfo) {
+ QualType BaseType = TInfo->getType();
+
// C++ [class.union]p1:
// A union shall not have base classes.
if (Class->isUnion()) {
@@ -461,8 +457,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
if (BaseType->isDependentType())
return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
- Class->getTagKind() == TTK_Class,
- Access, BaseType);
+ Class->getTagKind() == TTK_Class,
+ Access, TInfo);
+
+ SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
// Base specifiers must be record types.
if (!BaseType->isRecordType()) {
@@ -482,8 +480,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
// defined class.
if (RequireCompleteType(BaseLoc, BaseType,
PDiag(diag::err_incomplete_base_class)
- << SpecifierRange))
+ << SpecifierRange)) {
+ Class->setInvalidDecl();
return 0;
+ }
// If the base class is polymorphic or isn't empty, the new one is/isn't, too.
RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl();
@@ -502,11 +502,14 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
}
SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
+
+ if (BaseDecl->isInvalidDecl())
+ Class->setInvalidDecl();
// Create the base specifier.
return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
- Class->getTagKind() == TTK_Class,
- Access, BaseType);
+ Class->getTagKind() == TTK_Class,
+ Access, TInfo);
}
void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
@@ -581,22 +584,22 @@ void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
/// example:
/// class foo : public bar, virtual private baz {
/// 'public bar' and 'virtual private baz' are each base-specifiers.
-Sema::BaseResult
-Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange,
+BaseResult
+Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
bool Virtual, AccessSpecifier Access,
- TypeTy *basetype, SourceLocation BaseLoc) {
+ ParsedType basetype, SourceLocation BaseLoc) {
if (!classdecl)
return true;
AdjustDeclIfTemplate(classdecl);
- CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl.getAs<Decl>());
+ CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl);
if (!Class)
return true;
- QualType BaseType = GetTypeFromParser(basetype);
+ TypeSourceInfo *TInfo = 0;
+ GetTypeFromParser(basetype, &TInfo);
if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
- Virtual, Access,
- BaseType, BaseLoc))
+ Virtual, Access, TInfo))
return BaseSpec;
return true;
@@ -664,13 +667,13 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
/// ActOnBaseSpecifiers - Attach the given base specifiers to the
/// class, after checking whether there are any duplicate base
/// classes.
-void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, BaseTy **Bases,
unsigned NumBases) {
if (!ClassDecl || !Bases || !NumBases)
return;
AdjustDeclIfTemplate(ClassDecl);
- AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl.getAs<Decl>()),
+ AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl),
(CXXBaseSpecifier**)(Bases), NumBases);
}
@@ -719,7 +722,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) {
}
void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
- CXXBaseSpecifierArray &BasePathArray) {
+ CXXCastPath &BasePathArray) {
assert(BasePathArray.empty() && "Base path array must be empty!");
assert(Paths.isRecordingPaths() && "Must record paths!");
@@ -738,14 +741,14 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
// Now add all bases.
for (unsigned I = Start, E = Path.size(); I != E; ++I)
- BasePathArray.push_back(Path[I].Base);
+ BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base));
}
/// \brief Determine whether the given base path includes a virtual
/// base class.
-bool Sema::BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath) {
- for (CXXBaseSpecifierArray::iterator B = BasePath.begin(),
- BEnd = BasePath.end();
+bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) {
+ for (CXXCastPath::const_iterator B = BasePath.begin(),
+ BEnd = BasePath.end();
B != BEnd; ++B)
if ((*B)->isVirtual())
return true;
@@ -767,7 +770,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
- CXXBaseSpecifierArray *BasePath) {
+ CXXCastPath *BasePath) {
// First, determine whether the path from Derived to Base is
// ambiguous. This is slightly more expensive than checking whether
// the Derived to Base conversion exists, because here we need to
@@ -825,7 +828,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
bool
Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range,
- CXXBaseSpecifierArray *BasePath,
+ CXXCastPath *BasePath,
bool IgnoreAccess) {
return CheckDerivedToBaseConversion(Derived, Base,
IgnoreAccess ? 0
@@ -872,30 +875,31 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
//===----------------------------------------------------------------------===//
/// ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
-Sema::DeclPtrTy
-Sema::ActOnAccessSpecifier(AccessSpecifier Access,
- SourceLocation ASLoc, SourceLocation ColonLoc) {
+Decl *Sema::ActOnAccessSpecifier(AccessSpecifier Access,
+ SourceLocation ASLoc,
+ SourceLocation ColonLoc) {
assert(Access != AS_none && "Invalid kind for syntactic access specifier!");
- AccessSpecDecl* ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
+ AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
ASLoc, ColonLoc);
CurContext->addHiddenDecl(ASDecl);
- return DeclPtrTy::make(ASDecl);
+ return ASDecl;
}
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
/// bitfield width if there is one and 'InitExpr' specifies the initializer if
/// any.
-Sema::DeclPtrTy
+Decl *
Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BW, ExprTy *InitExpr, bool IsDefinition,
bool Deleted) {
const DeclSpec &DS = D.getDeclSpec();
- DeclarationName Name = GetNameForDeclarator(D);
+ DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+ DeclarationName Name = NameInfo.getName();
+ SourceLocation Loc = NameInfo.getLoc();
Expr *BitWidth = static_cast<Expr*>(BW);
Expr *Init = static_cast<Expr*>(InitExpr);
- SourceLocation Loc = D.getIdentifierLoc();
assert(isa<CXXRecordDecl>(CurContext));
assert(!DS.isFriendSpecified());
@@ -905,7 +909,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
isFunc = true;
else if (D.getNumTypeObjects() == 0 &&
D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
- QualType TDType = GetTypeFromParser(DS.getTypeRep());
+ QualType TDType = GetTypeFromParser(DS.getRepAsType());
isFunc = TDType->isFunctionType();
}
@@ -952,11 +956,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
AS);
assert(Member && "HandleField never returns null");
} else {
- Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition)
- .getAs<Decl>();
+ Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition);
if (!Member) {
- if (BitWidth) DeleteExpr(BitWidth);
- return DeclPtrTy();
+ return 0;
}
// Non-instance-fields can't have a bitfield.
@@ -980,7 +982,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
<< BitWidth->getSourceRange();
}
- DeleteExpr(BitWidth);
BitWidth = 0;
Member->setInvalidDecl();
}
@@ -996,15 +997,15 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
assert((Name || isInstField) && "No identifier for non-field ?");
if (Init)
- AddInitializerToDecl(DeclPtrTy::make(Member), ExprArg(*this, Init), false);
+ AddInitializerToDecl(Member, Init, false);
if (Deleted) // FIXME: Source location is not very good.
- SetDeclDeleted(DeclPtrTy::make(Member), D.getSourceRange().getBegin());
+ SetDeclDeleted(Member, D.getSourceRange().getBegin());
if (isInstField) {
FieldCollector->Add(cast<FieldDecl>(Member));
- return DeclPtrTy();
+ return 0;
}
- return DeclPtrTy::make(Member);
+ return Member;
}
/// \brief Find the direct and/or virtual base specifiers that
@@ -1053,12 +1054,12 @@ static bool FindBaseInitializer(Sema &SemaRef,
}
/// ActOnMemInitializer - Handle a C++ member initializer.
-Sema::MemInitResult
-Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
+MemInitResult
+Sema::ActOnMemInitializer(Decl *ConstructorD,
Scope *S,
CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
- TypeTy *TemplateTypeTy,
+ ParsedType TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -1070,7 +1071,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
AdjustDeclIfTemplate(ConstructorD);
CXXConstructorDecl *Constructor
- = dyn_cast<CXXConstructorDecl>(ConstructorD.getAs<Decl>());
+ = dyn_cast<CXXConstructorDecl>(ConstructorD);
if (!Constructor) {
// The user wrote a constructor initializer on a function that is
// not a C++ constructor. Ignore the error for now, because we may
@@ -1148,7 +1149,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
CorrectTypo(R, S, &SS, ClassDecl, 0, CTC_NoKeywords) &&
R.isSingleResult()) {
if (FieldDecl *Member = R.getAsSingle<FieldDecl>()) {
- if (Member->getDeclContext()->getLookupContext()->Equals(ClassDecl)) {
+ if (Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl)) {
// We have found a non-static data member with a similar
// name to what was typed; complain and initialize that
// member.
@@ -1259,7 +1260,7 @@ static bool InitExprContainsUninitializedFields(const Stmt *S,
return false;
}
-Sema::MemInitResult
+MemInitResult
Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
unsigned NumArgs, SourceLocation IdLoc,
SourceLocation LParenLoc,
@@ -1285,15 +1286,12 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
for (unsigned i = 0; i < NumArgs; i++)
HasDependentArg |= Args[i]->isTypeDependent();
- QualType FieldType = Member->getType();
- if (const ArrayType *Array = Context.getAsArrayType(FieldType))
- FieldType = Array->getElementType();
- if (FieldType->isDependentType() || HasDependentArg) {
+ if (Member->getType()->isDependentType() || HasDependentArg) {
// Can't check initialization for a member of dependent type or when
// any of the arguments are type-dependent expressions.
- OwningExprResult Init
- = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ Expr *Init
+ = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+ RParenLoc);
// Erase any temporaries within this evaluation context; we're not
// going to track them in the AST, since we'll be rebuilding the
@@ -1304,7 +1302,7 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
LParenLoc,
- Init.takeAs<Expr>(),
+ Init,
RParenLoc);
}
@@ -1320,16 +1318,16 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
- OwningExprResult MemberInit =
+ ExprResult MemberInit =
InitSeq.Perform(*this, MemberEntity, Kind,
- MultiExprArg(*this, (void**)Args, NumArgs), 0);
+ MultiExprArg(*this, Args, NumArgs), 0);
if (MemberInit.isInvalid())
return true;
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+ MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
if (MemberInit.isInvalid())
return true;
@@ -1345,22 +1343,21 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
for (unsigned I = 0; I != NumArgs; ++I)
Args[I]->Retain();
- OwningExprResult Init
- = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
- RParenLoc));
+ Expr *Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+ RParenLoc);
return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
LParenLoc,
- Init.takeAs<Expr>(),
+ Init,
RParenLoc);
}
return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
LParenLoc,
- MemberInit.takeAs<Expr>(),
+ MemberInit.get(),
RParenLoc);
}
-Sema::MemInitResult
+MemInitResult
Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
Expr **Args, unsigned NumArgs,
SourceLocation LParenLoc, SourceLocation RParenLoc,
@@ -1413,7 +1410,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
if (Dependent) {
// Can't check initialization for a base of dependent type or when
// any of the arguments are type-dependent expressions.
- OwningExprResult BaseInit
+ ExprResult BaseInit
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
RParenLoc));
@@ -1452,16 +1449,16 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
- OwningExprResult BaseInit =
+ ExprResult BaseInit =
InitSeq.Perform(*this, BaseEntity, Kind,
- MultiExprArg(*this, (void**)Args, NumArgs), 0);
+ MultiExprArg(*this, Args, NumArgs), 0);
if (BaseInit.isInvalid())
return true;
// C++0x [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- BaseInit = MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+ BaseInit = MaybeCreateCXXExprWithTemporaries(BaseInit.get());
if (BaseInit.isInvalid())
return true;
@@ -1477,7 +1474,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
for (unsigned I = 0; I != NumArgs; ++I)
Args[I]->Retain();
- OwningExprResult Init
+ ExprResult Init
= Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
RParenLoc));
return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo,
@@ -1512,7 +1509,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
= InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
IsInheritedVirtualBase);
- Sema::OwningExprResult BaseInit(SemaRef);
+ ExprResult BaseInit;
switch (ImplicitInitKind) {
case IIK_Default: {
@@ -1520,7 +1517,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
= InitializationKind::CreateDefault(Constructor->getLocation());
InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
- Sema::MultiExprArg(SemaRef, 0, 0));
+ MultiExprArg(SemaRef, 0, 0));
break;
}
@@ -1536,10 +1533,12 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
QualType ArgTy =
SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(),
ParamType.getQualifiers());
- SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
- CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/true,
- CXXBaseSpecifierArray(BaseSpec));
+
+ CXXCastPath BasePath;
+ BasePath.push_back(BaseSpec);
+ SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
+ CK_UncheckedDerivedToBase,
+ VK_LValue, &BasePath);
InitializationKind InitKind
= InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -1547,16 +1546,18 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationSequence InitSeq(SemaRef, InitEntity, InitKind,
&CopyCtorArg, 1);
BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
- Sema::MultiExprArg(SemaRef,
- (void**)&CopyCtorArg, 1));
+ MultiExprArg(&CopyCtorArg, 1));
break;
}
case IIK_Move:
assert(false && "Unhandled initializer kind!");
}
+
+ if (BaseInit.isInvalid())
+ return true;
- BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+ BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(BaseInit.get());
if (BaseInit.isInvalid())
return true;
@@ -1596,8 +1597,8 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
Sema::LookupMemberName);
MemberLookup.addDecl(Field, AS_public);
MemberLookup.resolveKind();
- Sema::OwningExprResult CopyCtorArg
- = SemaRef.BuildMemberReferenceExpr(SemaRef.Owned(MemberExprBase),
+ ExprResult CopyCtorArg
+ = SemaRef.BuildMemberReferenceExpr(MemberExprBase,
ParamType, Loc,
/*IsArrow=*/false,
SS,
@@ -1628,19 +1629,19 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
= VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc,
IterationVarName, SizeType,
SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc),
- VarDecl::None, VarDecl::None);
+ SC_None, SC_None);
IndexVariables.push_back(IterationVar);
// Create a reference to the iteration variable.
- Sema::OwningExprResult IterationVarRef
+ ExprResult IterationVarRef
= SemaRef.BuildDeclRefExpr(IterationVar, SizeType, Loc);
assert(!IterationVarRef.isInvalid() &&
"Reference to invented variable cannot fail!");
// Subscript the array with this iteration variable.
- CopyCtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(move(CopyCtorArg),
+ CopyCtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CopyCtorArg.take(),
Loc,
- move(IterationVarRef),
+ IterationVarRef.take(),
Loc);
if (CopyCtorArg.isInvalid())
return true;
@@ -1667,10 +1668,10 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind,
&CopyCtorArgE, 1);
- Sema::OwningExprResult MemberInit
+ ExprResult MemberInit
= InitSeq.Perform(SemaRef, Entities.back(), InitKind,
- Sema::MultiExprArg(SemaRef, (void**)&CopyCtorArgE, 1));
- MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+ MultiExprArg(&CopyCtorArgE, 1));
+ MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
if (MemberInit.isInvalid())
return true;
@@ -1693,17 +1694,19 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationKind::CreateDefault(Loc);
InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
- Sema::OwningExprResult MemberInit =
- InitSeq.Perform(SemaRef, InitEntity, InitKind,
- Sema::MultiExprArg(SemaRef, 0, 0));
- MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+ ExprResult MemberInit =
+ InitSeq.Perform(SemaRef, InitEntity, InitKind, MultiExprArg());
+ if (MemberInit.isInvalid())
+ return true;
+
+ MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
if (MemberInit.isInvalid())
return true;
CXXMemberInit =
new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context,
Field, Loc, Loc,
- MemberInit.takeAs<Expr>(),
+ MemberInit.get(),
Loc);
return false;
}
@@ -1797,6 +1800,9 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
// Once we've initialized a field of an anonymous union, the union
// field in the class is also initialized, so exit immediately.
return false;
+ } else if ((*FA)->isAnonymousStructOrUnion()) {
+ if (CollectFieldInitializer(Info, Top, *FA))
+ return true;
}
}
@@ -2147,7 +2153,7 @@ bool CheckRedundantUnionInit(Sema &S,
}
/// ActOnMemInitializers - Handle the member initializers for a constructor.
-void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
SourceLocation ColonLoc,
MemInitTy **meminits, unsigned NumMemInits,
bool AnyErrors) {
@@ -2157,7 +2163,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
AdjustDeclIfTemplate(ConstructorDecl);
CXXConstructorDecl *Constructor
- = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>());
+ = dyn_cast<CXXConstructorDecl>(ConstructorDecl);
if (!Constructor) {
Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
@@ -2292,35 +2298,30 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
}
}
-void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
+void Sema::ActOnDefaultCtorInitializers(Decl *CDtorDecl) {
if (!CDtorDecl)
return;
if (CXXConstructorDecl *Constructor
- = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
+ = dyn_cast<CXXConstructorDecl>(CDtorDecl))
SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false);
}
bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
- unsigned DiagID, AbstractDiagSelID SelID,
- const CXXRecordDecl *CurrentRD) {
+ unsigned DiagID, AbstractDiagSelID SelID) {
if (SelID == -1)
- return RequireNonAbstractType(Loc, T,
- PDiag(DiagID), CurrentRD);
+ return RequireNonAbstractType(Loc, T, PDiag(DiagID));
else
- return RequireNonAbstractType(Loc, T,
- PDiag(DiagID) << SelID, CurrentRD);
+ return RequireNonAbstractType(Loc, T, PDiag(DiagID) << SelID);
}
bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
- const PartialDiagnostic &PD,
- const CXXRecordDecl *CurrentRD) {
+ const PartialDiagnostic &PD) {
if (!getLangOptions().CPlusPlus)
return false;
if (const ArrayType *AT = Context.getAsArrayType(T))
- return RequireNonAbstractType(Loc, AT->getElementType(), PD,
- CurrentRD);
+ return RequireNonAbstractType(Loc, AT->getElementType(), PD);
if (const PointerType *PT = T->getAs<PointerType>()) {
// Find the innermost pointer type.
@@ -2328,7 +2329,7 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
PT = T;
if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))
- return RequireNonAbstractType(Loc, AT->getElementType(), PD, CurrentRD);
+ return RequireNonAbstractType(Loc, AT->getElementType(), PD);
}
const RecordType *RT = T->getAs<RecordType>();
@@ -2337,22 +2338,27 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (CurrentRD && CurrentRD != RD)
- return false;
-
- // FIXME: is this reasonable? It matches current behavior, but....
- if (!RD->getDefinition())
+ // We can't answer whether something is abstract until it has a
+ // definition. If it's currently being defined, we'll walk back
+ // over all the declarations when we have a full definition.
+ const CXXRecordDecl *Def = RD->getDefinition();
+ if (!Def || Def->isBeingDefined())
return false;
if (!RD->isAbstract())
return false;
Diag(Loc, PD) << RD->getDeclName();
+ DiagnoseAbstractType(RD);
- // Check if we've already emitted the list of pure virtual functions for this
- // class.
+ return true;
+}
+
+void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) {
+ // Check if we've already emitted the list of pure virtual functions
+ // for this class.
if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD))
- return true;
+ return;
CXXFinalOverriderMap FinalOverriders;
RD->getFinalOverriders(FinalOverriders);
@@ -2392,69 +2398,168 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
if (!PureVirtualClassDiagSet)
PureVirtualClassDiagSet.reset(new RecordDeclSetTy);
PureVirtualClassDiagSet->insert(RD);
-
- return true;
}
namespace {
- class AbstractClassUsageDiagnoser
- : public DeclVisitor<AbstractClassUsageDiagnoser, bool> {
- Sema &SemaRef;
- CXXRecordDecl *AbstractClass;
+struct AbstractUsageInfo {
+ Sema &S;
+ CXXRecordDecl *Record;
+ CanQualType AbstractType;
+ bool Invalid;
+
+ AbstractUsageInfo(Sema &S, CXXRecordDecl *Record)
+ : S(S), Record(Record),
+ AbstractType(S.Context.getCanonicalType(
+ S.Context.getTypeDeclType(Record))),
+ Invalid(false) {}
+
+ void DiagnoseAbstractType() {
+ if (Invalid) return;
+ S.DiagnoseAbstractType(Record);
+ Invalid = true;
+ }
- bool VisitDeclContext(const DeclContext *DC) {
- bool Invalid = false;
+ void CheckType(const NamedDecl *D, TypeLoc TL, Sema::AbstractDiagSelID Sel);
+};
- for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
- E = DC->decls_end(); I != E; ++I)
- Invalid |= Visit(*I);
+struct CheckAbstractUsage {
+ AbstractUsageInfo &Info;
+ const NamedDecl *Ctx;
- return Invalid;
+ CheckAbstractUsage(AbstractUsageInfo &Info, const NamedDecl *Ctx)
+ : Info(Info), Ctx(Ctx) {}
+
+ void Visit(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+ switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: Check(cast<CLASS##TypeLoc>(TL), Sel); break;
+#include "clang/AST/TypeLocNodes.def"
}
+ }
- public:
- AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
- : SemaRef(SemaRef), AbstractClass(ac) {
- Visit(SemaRef.Context.getTranslationUnitDecl());
+ void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+ Visit(TL.getResultLoc(), Sema::AbstractReturnType);
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TypeSourceInfo *TSI = TL.getArg(I)->getTypeSourceInfo();
+ if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType);
}
+ }
- bool VisitFunctionDecl(const FunctionDecl *FD) {
- if (FD->isThisDeclarationADefinition()) {
- // No need to do the check if we're in a definition, because it requires
- // that the return/param types are complete.
- // because that requires
- return VisitDeclContext(FD);
- }
+ void Check(ArrayTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+ Visit(TL.getElementLoc(), Sema::AbstractArrayType);
+ }
- // Check the return type.
- QualType RTy = FD->getType()->getAs<FunctionType>()->getResultType();
- bool Invalid =
- SemaRef.RequireNonAbstractType(FD->getLocation(), RTy,
- diag::err_abstract_type_in_decl,
- Sema::AbstractReturnType,
- AbstractClass);
-
- for (FunctionDecl::param_const_iterator I = FD->param_begin(),
- E = FD->param_end(); I != E; ++I) {
- const ParmVarDecl *VD = *I;
- Invalid |=
- SemaRef.RequireNonAbstractType(VD->getLocation(),
- VD->getOriginalType(),
- diag::err_abstract_type_in_decl,
- Sema::AbstractParamType,
- AbstractClass);
- }
+ void Check(TemplateSpecializationTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+ // Visit the type parameters from a permissive context.
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TemplateArgumentLoc TAL = TL.getArgLoc(I);
+ if (TAL.getArgument().getKind() == TemplateArgument::Type)
+ if (TypeSourceInfo *TSI = TAL.getTypeSourceInfo())
+ Visit(TSI->getTypeLoc(), Sema::AbstractNone);
+ // TODO: other template argument types?
+ }
+ }
- return Invalid;
+ // Visit pointee types from a permissive context.
+#define CheckPolymorphic(Type) \
+ void Check(Type TL, Sema::AbstractDiagSelID Sel) { \
+ Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \
+ }
+ CheckPolymorphic(PointerTypeLoc)
+ CheckPolymorphic(ReferenceTypeLoc)
+ CheckPolymorphic(MemberPointerTypeLoc)
+ CheckPolymorphic(BlockPointerTypeLoc)
+
+ /// Handle all the types we haven't given a more specific
+ /// implementation for above.
+ void Check(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+ // Every other kind of type that we haven't called out already
+ // that has an inner type is either (1) sugar or (2) contains that
+ // inner type in some way as a subobject.
+ if (TypeLoc Next = TL.getNextTypeLoc())
+ return Visit(Next, Sel);
+
+ // If there's no inner type and we're in a permissive context,
+ // don't diagnose.
+ if (Sel == Sema::AbstractNone) return;
+
+ // Check whether the type matches the abstract type.
+ QualType T = TL.getType();
+ if (T->isArrayType()) {
+ Sel = Sema::AbstractArrayType;
+ T = Info.S.Context.getBaseElementType(T);
}
+ CanQualType CT = T->getCanonicalTypeUnqualified().getUnqualifiedType();
+ if (CT != Info.AbstractType) return;
- bool VisitDecl(const Decl* D) {
- if (const DeclContext *DC = dyn_cast<DeclContext>(D))
- return VisitDeclContext(DC);
+ // It matched; do some magic.
+ if (Sel == Sema::AbstractArrayType) {
+ Info.S.Diag(Ctx->getLocation(), diag::err_array_of_abstract_type)
+ << T << TL.getSourceRange();
+ } else {
+ Info.S.Diag(Ctx->getLocation(), diag::err_abstract_type_in_decl)
+ << Sel << T << TL.getSourceRange();
+ }
+ Info.DiagnoseAbstractType();
+ }
+};
- return false;
+void AbstractUsageInfo::CheckType(const NamedDecl *D, TypeLoc TL,
+ Sema::AbstractDiagSelID Sel) {
+ CheckAbstractUsage(*this, D).Visit(TL, Sel);
+}
+
+}
+
+/// Check for invalid uses of an abstract type in a method declaration.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+ CXXMethodDecl *MD) {
+ // No need to do the check on definitions, which require that
+ // the return/param types be complete.
+ if (MD->isThisDeclarationADefinition())
+ return;
+
+ // For safety's sake, just ignore it if we don't have type source
+ // information. This should never happen for non-implicit methods,
+ // but...
+ if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
+ Info.CheckType(MD, TSI->getTypeLoc(), Sema::AbstractNone);
+}
+
+/// Check for invalid uses of an abstract type within a class definition.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+ CXXRecordDecl *RD) {
+ for (CXXRecordDecl::decl_iterator
+ I = RD->decls_begin(), E = RD->decls_end(); I != E; ++I) {
+ Decl *D = *I;
+ if (D->isImplicit()) continue;
+
+ // Methods and method templates.
+ if (isa<CXXMethodDecl>(D)) {
+ CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(D));
+ } else if (isa<FunctionTemplateDecl>(D)) {
+ FunctionDecl *FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl();
+ CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(FD));
+
+ // Fields and static variables.
+ } else if (isa<FieldDecl>(D)) {
+ FieldDecl *FD = cast<FieldDecl>(D);
+ if (TypeSourceInfo *TSI = FD->getTypeSourceInfo())
+ Info.CheckType(FD, TSI->getTypeLoc(), Sema::AbstractFieldType);
+ } else if (isa<VarDecl>(D)) {
+ VarDecl *VD = cast<VarDecl>(D);
+ if (TypeSourceInfo *TSI = VD->getTypeSourceInfo())
+ Info.CheckType(VD, TSI->getTypeLoc(), Sema::AbstractVariableType);
+
+ // Nested classes and class templates.
+ } else if (isa<CXXRecordDecl>(D)) {
+ CheckAbstractClassUsage(Info, cast<CXXRecordDecl>(D));
+ } else if (isa<ClassTemplateDecl>(D)) {
+ CheckAbstractClassUsage(Info,
+ cast<ClassTemplateDecl>(D)->getTemplatedDecl());
}
- };
+ }
}
/// \brief Perform semantic checks on a class definition that has been
@@ -2539,8 +2644,10 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
}
}
- if (Record->isAbstract() && !Record->isInvalidDecl())
- (void)AbstractClassUsageDiagnoser(*this, Record);
+ if (Record->isAbstract() && !Record->isInvalidDecl()) {
+ AbstractUsageInfo Info(*this, Record);
+ CheckAbstractClassUsage(Info, Record);
+ }
// If this is not an aggregate type and has no user-declared constructor,
// complain about any non-static data members of reference or const scalar
@@ -2571,7 +2678,7 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
}
void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
- DeclPtrTy TagDecl,
+ Decl *TagDecl,
SourceLocation LBrac,
SourceLocation RBrac,
AttributeList *AttrList) {
@@ -2581,11 +2688,12 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
AdjustDeclIfTemplate(TagDecl);
ActOnFields(S, RLoc, TagDecl,
- (DeclPtrTy*)FieldCollector->getCurFields(),
+ // strict aliasing violation!
+ reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList);
CheckCompletedCXXClass(
- dyn_cast_or_null<CXXRecordDecl>(TagDecl.getAs<Decl>()));
+ dyn_cast_or_null<CXXRecordDecl>(TagDecl));
}
namespace {
@@ -2682,8 +2790,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
}
-void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
- Decl *D = TemplateD.getAs<Decl>();
+void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
if (!D)
return;
@@ -2701,20 +2808,20 @@ void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
Param != ParamEnd; ++Param) {
NamedDecl *Named = cast<NamedDecl>(*Param);
if (Named->getDeclName()) {
- S->AddDecl(DeclPtrTy::make(Named));
+ S->AddDecl(Named);
IdResolver.AddDecl(Named);
}
}
}
-void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
if (!RecordD) return;
AdjustDeclIfTemplate(RecordD);
- CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD.getAs<Decl>());
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD);
PushDeclContext(S, Record);
}
-void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
if (!RecordD) return;
PopDeclContext();
}
@@ -2727,7 +2834,7 @@ void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
/// Method declaration as if we had just parsed the qualified method
/// name. However, it should not bring the parameters into scope;
/// that will be performed by ActOnDelayedCXXMethodParameter.
-void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
}
/// ActOnDelayedCXXMethodParameter - We've already started a delayed
@@ -2735,18 +2842,18 @@ void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
/// function parameter into scope for use in parsing later parts of
/// the method declaration. For example, we could see an
/// ActOnParamDefaultArgument event for this parameter.
-void Sema::ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy ParamD) {
+void Sema::ActOnDelayedCXXMethodParameter(Scope *S, Decl *ParamD) {
if (!ParamD)
return;
- ParmVarDecl *Param = cast<ParmVarDecl>(ParamD.getAs<Decl>());
+ ParmVarDecl *Param = cast<ParmVarDecl>(ParamD);
// If this parameter has an unparsed default argument, clear it out
// to make way for the parsed default argument.
if (Param->hasUnparsedDefaultArg())
Param->setDefaultArg(0);
- S->AddDecl(DeclPtrTy::make(Param));
+ S->AddDecl(Param);
if (Param->getDeclName())
IdResolver.AddDecl(Param);
}
@@ -2757,13 +2864,13 @@ void Sema::ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy ParamD) {
/// ActOnStartOfFunctionDef action later (not necessarily
/// immediately!) for this method, if it was also defined inside the
/// class body.
-void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
if (!MethodD)
return;
AdjustDeclIfTemplate(MethodD);
- FunctionDecl *Method = cast<FunctionDecl>(MethodD.getAs<Decl>());
+ FunctionDecl *Method = cast<FunctionDecl>(MethodD);
// Now that we have our default arguments, check the constructor
// again. It could produce additional diagnostics or affect whether
@@ -2784,7 +2891,7 @@ void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
/// will be updated to reflect a well-formed type for the constructor and
/// returned.
QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
- FunctionDecl::StorageClass &SC) {
+ StorageClass &SC) {
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
// C++ [class.ctor]p3:
@@ -2799,13 +2906,13 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
<< SourceRange(D.getIdentifierLoc());
D.setInvalidType();
}
- if (SC == FunctionDecl::Static) {
+ if (SC == SC_Static) {
if (!D.isInvalidType())
Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
<< "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
<< SourceRange(D.getIdentifierLoc());
D.setInvalidType();
- SC = FunctionDecl::None;
+ SC = SC_None;
}
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
@@ -2879,8 +2986,9 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
ClassDecl->addedConstructor(Context, Constructor);
}
-/// CheckDestructor - Checks a fully-formed destructor for well-formedness,
-/// issuing any diagnostics required. Returns true on error.
+/// CheckDestructor - Checks a fully-formed destructor definition for
+/// well-formedness, issuing any diagnostics required. Returns true
+/// on error.
bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
CXXRecordDecl *RD = Destructor->getParent();
@@ -2911,7 +3019,7 @@ static inline bool
FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
return (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
FTI.ArgInfo[0].Param &&
- FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType());
+ cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType());
}
/// CheckDestructorDeclarator - Called by ActOnDeclarator to check
@@ -2921,7 +3029,7 @@ FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
/// will be updated to reflect a well-formed type for the destructor and
/// returned.
QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
- FunctionDecl::StorageClass& SC) {
+ StorageClass& SC) {
// C++ [class.dtor]p1:
// [...] A typedef-name that names a class is a class-name
// (7.1.3); however, a typedef-name that names a class shall not
@@ -2940,14 +3048,14 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
// destructor can be invoked for a const, volatile or const
// volatile object. A destructor shall not be declared const,
// volatile or const volatile (9.3.2).
- if (SC == FunctionDecl::Static) {
+ if (SC == SC_Static) {
if (!D.isInvalidType())
Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
<< "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
<< SourceRange(D.getIdentifierLoc())
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
- SC = FunctionDecl::None;
+ SC = SC_None;
}
if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
// Destructors don't have return types, but the parser will
@@ -3015,18 +3123,18 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
/// false. Either way, the type @p R will be updated to reflect a
/// well-formed type for the conversion operator.
void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
- FunctionDecl::StorageClass& SC) {
+ StorageClass& SC) {
// C++ [class.conv.fct]p1:
// Neither parameter types nor return type can be specified. The
// type of a conversion function (8.3.5) is "function taking no
// parameter returning conversion-type-id."
- if (SC == FunctionDecl::Static) {
+ if (SC == SC_Static) {
if (!D.isInvalidType())
Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member)
<< "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
<< SourceRange(D.getIdentifierLoc());
D.setInvalidType();
- SC = FunctionDecl::None;
+ SC = SC_None;
}
QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId);
@@ -3106,7 +3214,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
/// the declaration of the given C++ conversion function. This routine
/// is responsible for recording the conversion function in the C++
/// class, if possible.
-Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
+Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
assert(Conversion && "Expected to receive a conversion function declaration");
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext());
@@ -3147,10 +3255,10 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
if (ClassDecl->replaceConversion(
ConversionTemplate->getPreviousDeclaration(),
ConversionTemplate))
- return DeclPtrTy::make(ConversionTemplate);
+ return ConversionTemplate;
} else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
Conversion))
- return DeclPtrTy::make(Conversion);
+ return Conversion;
assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
} else if (FunctionTemplateDecl *ConversionTemplate
= Conversion->getDescribedFunctionTemplate())
@@ -3158,28 +3266,36 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
else
ClassDecl->addConversionFunction(Conversion);
- return DeclPtrTy::make(Conversion);
+ return Conversion;
}
//===----------------------------------------------------------------------===//
// Namespace Handling
//===----------------------------------------------------------------------===//
+
+
/// ActOnStartNamespaceDef - This is called at the start of a namespace
/// definition.
-Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
- SourceLocation IdentLoc,
- IdentifierInfo *II,
- SourceLocation LBrace,
- AttributeList *AttrList) {
- NamespaceDecl *Namespc =
- NamespaceDecl::Create(Context, CurContext, IdentLoc, II);
+Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
+ SourceLocation InlineLoc,
+ SourceLocation IdentLoc,
+ IdentifierInfo *II,
+ SourceLocation LBrace,
+ AttributeList *AttrList) {
+ // anonymous namespace starts at its left brace
+ NamespaceDecl *Namespc = NamespaceDecl::Create(Context, CurContext,
+ (II ? IdentLoc : LBrace) , II);
Namespc->setLBracLoc(LBrace);
+ Namespc->setInline(InlineLoc.isValid());
Scope *DeclRegionScope = NamespcScope->getParent();
ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+ if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
+ PushVisibilityAttr(attr);
+
if (II) {
// C++ [namespace.def]p2:
// The identifier in an original-namespace-definition shall not have been
@@ -3194,15 +3310,25 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
// This is an extended namespace definition.
+ if (Namespc->isInline() != OrigNS->isInline()) {
+ // inline-ness must match
+ Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch)
+ << Namespc->isInline();
+ Diag(OrigNS->getLocation(), diag::note_previous_definition);
+ Namespc->setInvalidDecl();
+ // Recover by ignoring the new namespace's inline status.
+ Namespc->setInline(OrigNS->isInline());
+ }
+
// Attach this namespace decl to the chain of extended namespace
// definitions.
OrigNS->setNextNamespace(Namespc);
Namespc->setOriginalNamespace(OrigNS->getOriginalNamespace());
// Remove the previous declaration from the scope.
- if (DeclRegionScope->isDeclScope(DeclPtrTy::make(OrigNS))) {
+ if (DeclRegionScope->isDeclScope(OrigNS)) {
IdResolver.RemoveDecl(OrigNS);
- DeclRegionScope->RemoveDecl(DeclPtrTy::make(OrigNS));
+ DeclRegionScope->RemoveDecl(OrigNS);
}
} else if (PrevDecl) {
// This is an invalid name redefinition.
@@ -3212,15 +3338,15 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
Namespc->setInvalidDecl();
// Continue on to push Namespc as current DeclContext and return it.
} else if (II->isStr("std") &&
- CurContext->getLookupContext()->isTranslationUnit()) {
+ CurContext->getRedeclContext()->isTranslationUnit()) {
// This is the first "real" definition of the namespace "std", so update
// our cache of the "std" namespace to point at this definition.
- if (StdNamespace) {
+ if (NamespaceDecl *StdNS = getStdNamespace()) {
// We had already defined a dummy namespace "std". Link this new
// namespace definition to the dummy namespace "std".
- StdNamespace->setNextNamespace(Namespc);
- StdNamespace->setLocation(IdentLoc);
- Namespc->setOriginalNamespace(StdNamespace->getOriginalNamespace());
+ StdNS->setNextNamespace(Namespc);
+ StdNS->setLocation(IdentLoc);
+ Namespc->setOriginalNamespace(StdNS->getOriginalNamespace());
}
// Make our StdNamespace cache point at the first real definition of the
@@ -3235,7 +3361,7 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
// Link the anonymous namespace into its parent.
NamespaceDecl *PrevDecl;
- DeclContext *Parent = CurContext->getLookupContext();
+ DeclContext *Parent = CurContext->getRedeclContext();
if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) {
PrevDecl = TU->getAnonymousNamespace();
TU->setAnonymousNamespace(Namespc);
@@ -3251,6 +3377,16 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
assert(!PrevDecl->getNextNamespace());
Namespc->setOriginalNamespace(PrevDecl->getOriginalNamespace());
PrevDecl->setNextNamespace(Namespc);
+
+ if (Namespc->isInline() != PrevDecl->isInline()) {
+ // inline-ness must match
+ Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch)
+ << Namespc->isInline();
+ Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+ Namespc->setInvalidDecl();
+ // Recover by ignoring the new namespace's inline status.
+ Namespc->setInline(PrevDecl->isInline());
+ }
}
CurContext->addDecl(Namespc);
@@ -3292,7 +3428,7 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
// for the namespace has the declarations that showed up in that particular
// namespace definition.
PushDeclContext(NamespcScope, Namespc);
- return DeclPtrTy::make(Namespc);
+ return Namespc;
}
/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
@@ -3305,30 +3441,41 @@ static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
/// ActOnFinishNamespaceDef - This callback is called after a namespace is
/// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
-void Sema::ActOnFinishNamespaceDef(DeclPtrTy D, SourceLocation RBrace) {
- Decl *Dcl = D.getAs<Decl>();
+void Sema::ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace) {
NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
assert(Namespc && "Invalid parameter, expected NamespaceDecl");
Namespc->setRBracLoc(RBrace);
PopDeclContext();
+ if (Namespc->hasAttr<VisibilityAttr>())
+ PopPragmaVisibility();
+}
+
+CXXRecordDecl *Sema::getStdBadAlloc() const {
+ return cast_or_null<CXXRecordDecl>(
+ StdBadAlloc.get(Context.getExternalSource()));
+}
+
+NamespaceDecl *Sema::getStdNamespace() const {
+ return cast_or_null<NamespaceDecl>(
+ StdNamespace.get(Context.getExternalSource()));
}
/// \brief Retrieve the special "std" namespace, which may require us to
/// implicitly define the namespace.
-NamespaceDecl *Sema::getStdNamespace() {
+NamespaceDecl *Sema::getOrCreateStdNamespace() {
if (!StdNamespace) {
// The "std" namespace has not yet been defined, so build one implicitly.
StdNamespace = NamespaceDecl::Create(Context,
Context.getTranslationUnitDecl(),
SourceLocation(),
&PP.getIdentifierTable().get("std"));
- StdNamespace->setImplicit(true);
+ getStdNamespace()->setImplicit(true);
}
- return StdNamespace;
+ return getStdNamespace();
}
-Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
+Decl *Sema::ActOnUsingDirective(Scope *S,
SourceLocation UsingLoc,
SourceLocation NamespcLoc,
CXXScopeSpec &SS,
@@ -3349,7 +3496,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
LookupParsedName(R, S, &SS);
if (R.isAmbiguous())
- return DeclPtrTy();
+ return 0;
if (R.empty()) {
// Allow "using namespace std;" or "using namespace ::std;" even if
@@ -3357,7 +3504,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) &&
NamespcName->isStr("std")) {
Diag(IdentLoc, diag::ext_using_undefined_std);
- R.addDecl(getStdNamespace());
+ R.addDecl(getOrCreateStdNamespace());
R.resolveKind();
}
// Otherwise, attempt typo correction.
@@ -3416,7 +3563,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
// FIXME: We ignore attributes for now.
delete AttrList;
- return DeclPtrTy::make(UDir);
+ return UDir;
}
void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
@@ -3428,11 +3575,11 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
else
// Otherwise it is block-sope. using-directives will affect lookup
// only to the end of scope.
- S->PushUsingDirective(DeclPtrTy::make(UDir));
+ S->PushUsingDirective(UDir);
}
-Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
+Decl *Sema::ActOnUsingDeclaration(Scope *S,
AccessSpecifier AS,
bool HasUsingKeyword,
SourceLocation UsingLoc,
@@ -3457,22 +3604,23 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
<< SS.getRange();
- return DeclPtrTy();
+ return 0;
case UnqualifiedId::IK_DestructorName:
Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_destructor)
<< SS.getRange();
- return DeclPtrTy();
+ return 0;
case UnqualifiedId::IK_TemplateId:
Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_template_id)
<< SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
- return DeclPtrTy();
+ return 0;
}
-
- DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
+
+ DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
+ DeclarationName TargetName = TargetNameInfo.getName();
if (!TargetName)
- return DeclPtrTy();
+ return 0;
// Warn about using declarations.
// TODO: store that the declaration was written without 'using' and
@@ -3486,14 +3634,13 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
}
NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
- Name.getSourceRange().getBegin(),
- TargetName, AttrList,
+ TargetNameInfo, AttrList,
/* IsInstantiation */ false,
IsTypeName, TypenameLoc);
if (UD)
PushOnScopeChains(UD, S, /*AddToContext*/ false);
- return DeclPtrTy::make(UD);
+ return UD;
}
/// \brief Determine whether a using declaration considers the given
@@ -3717,7 +3864,7 @@ void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
// ...and the scope, if applicable...
if (S) {
- S->RemoveDecl(DeclPtrTy::make(static_cast<Decl*>(Shadow)));
+ S->RemoveDecl(Shadow);
IdResolver.RemoveDecl(Shadow);
}
@@ -3736,13 +3883,13 @@ void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
CXXScopeSpec &SS,
- SourceLocation IdentLoc,
- DeclarationName Name,
+ const DeclarationNameInfo &NameInfo,
AttributeList *AttrList,
bool IsInstantiation,
bool IsTypeName,
SourceLocation TypenameLoc) {
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
+ SourceLocation IdentLoc = NameInfo.getLoc();
assert(IdentLoc.isValid() && "Invalid TargetName location.");
// FIXME: We ignore attributes for now.
@@ -3754,7 +3901,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
}
// Do the redeclaration lookup in the current scope.
- LookupResult Previous(*this, Name, IdentLoc, LookupUsingDeclName,
+ LookupResult Previous(*this, NameInfo, LookupUsingDeclName,
ForRedeclaration);
Previous.setHideTags(false);
if (S) {
@@ -3793,15 +3940,15 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
UsingLoc, TypenameLoc,
SS.getRange(), NNS,
- IdentLoc, Name);
+ IdentLoc, NameInfo.getName());
} else {
D = UnresolvedUsingValueDecl::Create(Context, CurContext,
- UsingLoc, SS.getRange(), NNS,
- IdentLoc, Name);
+ UsingLoc, SS.getRange(),
+ NNS, NameInfo);
}
} else {
- D = UsingDecl::Create(Context, CurContext, IdentLoc,
- SS.getRange(), UsingLoc, NNS, Name,
+ D = UsingDecl::Create(Context, CurContext,
+ SS.getRange(), UsingLoc, NNS, NameInfo,
IsTypeName);
}
D->setAccess(AS);
@@ -3817,7 +3964,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
// Look up the target name.
- LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
// Unlike most lookups, we don't always want to hide tag
// declarations: tag names are visible through the using declaration
@@ -3830,7 +3977,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
if (R.empty()) {
Diag(IdentLoc, diag::err_no_member)
- << Name << LookupContext << SS.getRange();
+ << NameInfo.getName() << LookupContext << SS.getRange();
UD->setInvalidDecl();
return UD;
}
@@ -3894,7 +4041,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
// allowed.
//
// That's in non-member contexts.
- if (!CurContext->getLookupContext()->isRecord())
+ if (!CurContext->getRedeclContext()->isRecord())
return false;
NestedNameSpecifier *Qual
@@ -4069,7 +4216,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
return true;
}
-Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
+Decl *Sema::ActOnNamespaceAliasDef(Scope *S,
SourceLocation NamespaceLoc,
SourceLocation AliasLoc,
IdentifierInfo *Alias,
@@ -4096,18 +4243,18 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
// declaration to maintain better source information.
if (!R.isAmbiguous() && !R.empty() &&
AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl())))
- return DeclPtrTy();
+ return 0;
}
unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition :
diag::err_redefinition_different_kind;
Diag(AliasLoc, DiagID) << Alias;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- return DeclPtrTy();
+ return 0;
}
if (R.isAmbiguous())
- return DeclPtrTy();
+ return 0;
if (R.empty()) {
if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false,
@@ -4135,7 +4282,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
if (R.empty()) {
Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
- return DeclPtrTy();
+ return 0;
}
}
@@ -4146,7 +4293,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
IdentLoc, R.getFoundDecl());
PushOnScopeChains(AliasDecl, S);
- return DeclPtrTy::make(AliasDecl);
+ return AliasDecl;
}
namespace {
@@ -4242,9 +4389,9 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
= Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
+ DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
CXXConstructorDecl *DefaultCon
- = CXXConstructorDecl::Create(Context, ClassDecl,
- ClassDecl->getLocation(), Name,
+ = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
Context.getFunctionType(Context.VoidTy,
0, 0, false, 0,
ExceptSpec.hasExceptionSpecification(),
@@ -4348,9 +4495,9 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
= Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType);
+ DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
CXXDestructorDecl *Destructor
- = CXXDestructorDecl::Create(Context, ClassDecl,
- ClassDecl->getLocation(), Name, Ty,
+ = CXXDestructorDecl::Create(Context, ClassDecl, NameInfo, Ty,
/*isInline=*/true,
/*isImplicitlyDeclared=*/true);
Destructor->setAccess(AS_public);
@@ -4426,13 +4573,10 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
/// \param Depth Internal parameter recording the depth of the recursion.
///
/// \returns A statement or a loop that copies the expressions.
-static Sema::OwningStmtResult
+static StmtResult
BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
- Sema::OwningExprResult To, Sema::OwningExprResult From,
+ Expr *To, Expr *From,
bool CopyingBaseSubobject, unsigned Depth = 0) {
- typedef Sema::OwningStmtResult OwningStmtResult;
- typedef Sema::OwningExprResult OwningExprResult;
-
// C++0x [class.copy]p30:
// Each subobject is assigned in the manner appropriate to its type:
//
@@ -4489,21 +4633,21 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
T.getTypePtr()));
// Create the reference to operator=.
- OwningExprResult OpEqualRef
- = S.BuildMemberReferenceExpr(move(To), T, Loc, /*isArrow=*/false, SS,
+ ExprResult OpEqualRef
+ = S.BuildMemberReferenceExpr(To, T, Loc, /*isArrow=*/false, SS,
/*FirstQualifierInScope=*/0, OpLookup,
/*TemplateArgs=*/0,
/*SuppressQualifierCheck=*/true);
if (OpEqualRef.isInvalid())
- return S.StmtError();
+ return StmtError();
// Build the call to the assignment operator.
- Expr *FromE = From.takeAs<Expr>();
- OwningExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0,
+
+ ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0,
OpEqualRef.takeAs<Expr>(),
- Loc, &FromE, 1, 0, Loc);
+ Loc, &From, 1, 0, Loc);
if (Call.isInvalid())
- return S.StmtError();
+ return StmtError();
return S.Owned(Call.takeAs<Stmt>());
}
@@ -4512,12 +4656,9 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
// operator is used.
const ConstantArrayType *ArrayTy = S.Context.getAsConstantArrayType(T);
if (!ArrayTy) {
- OwningExprResult Assignment = S.CreateBuiltinBinOp(Loc,
- BinaryOperator::Assign,
- To.takeAs<Expr>(),
- From.takeAs<Expr>());
+ ExprResult Assignment = S.CreateBuiltinBinOp(Loc, BO_Assign, To, From);
if (Assignment.isInvalid())
- return S.StmtError();
+ return StmtError();
return S.Owned(Assignment.takeAs<Stmt>());
}
@@ -4543,11 +4684,11 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
VarDecl *IterationVar = VarDecl::Create(S.Context, S.CurContext, Loc,
IterationVarName, SizeType,
S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
- VarDecl::None, VarDecl::None);
+ SC_None, SC_None);
// Initialize the iteration variable to zero.
llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0);
- IterationVar->setInit(new (S.Context) IntegerLiteral(Zero, SizeType, Loc));
+ IterationVar->setInit(IntegerLiteral::Create(S.Context, Zero, SizeType, Loc));
// Create a reference to the iteration variable; we'll use this several
// times throughout.
@@ -4561,43 +4702,37 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
// Create the comparison against the array bound.
llvm::APInt Upper = ArrayTy->getSize();
Upper.zextOrTrunc(S.Context.getTypeSize(SizeType));
- OwningExprResult Comparison
- = S.Owned(new (S.Context) BinaryOperator(IterationVarRef->Retain(),
- new (S.Context) IntegerLiteral(Upper, SizeType, Loc),
- BinaryOperator::NE, S.Context.BoolTy, Loc));
+ Expr *Comparison
+ = new (S.Context) BinaryOperator(IterationVarRef->Retain(),
+ IntegerLiteral::Create(S.Context,
+ Upper, SizeType, Loc),
+ BO_NE, S.Context.BoolTy, Loc);
// Create the pre-increment of the iteration variable.
- OwningExprResult Increment
- = S.Owned(new (S.Context) UnaryOperator(IterationVarRef->Retain(),
- UnaryOperator::PreInc,
- SizeType, Loc));
+ Expr *Increment
+ = new (S.Context) UnaryOperator(IterationVarRef->Retain(),
+ UO_PreInc,
+ SizeType, Loc);
// Subscript the "from" and "to" expressions with the iteration variable.
- From = S.CreateBuiltinArraySubscriptExpr(move(From), Loc,
- S.Owned(IterationVarRef->Retain()),
- Loc);
- To = S.CreateBuiltinArraySubscriptExpr(move(To), Loc,
- S.Owned(IterationVarRef->Retain()),
- Loc);
- assert(!From.isInvalid() && "Builtin subscripting can't fail!");
- assert(!To.isInvalid() && "Builtin subscripting can't fail!");
+ From = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(From, Loc,
+ IterationVarRef, Loc));
+ To = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(To, Loc,
+ IterationVarRef, Loc));
// Build the copy for an individual element of the array.
- OwningStmtResult Copy = BuildSingleCopyAssign(S, Loc,
+ StmtResult Copy = BuildSingleCopyAssign(S, Loc,
ArrayTy->getElementType(),
- move(To), move(From),
+ To, From,
CopyingBaseSubobject, Depth+1);
- if (Copy.isInvalid()) {
- InitStmt->Destroy(S.Context);
- return S.StmtError();
- }
+ if (Copy.isInvalid())
+ return StmtError();
// Construct the loop that copies all elements of this array.
- return S.ActOnForStmt(Loc, Loc, S.Owned(InitStmt),
+ return S.ActOnForStmt(Loc, Loc, InitStmt,
S.MakeFullExpr(Comparison),
- Sema::DeclPtrTy(),
- S.MakeFullExpr(Increment),
- Loc, move(Copy));
+ 0, S.MakeFullExpr(Increment),
+ Loc, Copy.take());
}
/// \brief Determine whether the given class has a copy assignment operator
@@ -4747,8 +4882,9 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
// An implicitly-declared copy assignment operator is an inline public
// member of its class.
DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+ DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
CXXMethodDecl *CopyAssignment
- = CXXMethodDecl::Create(Context, ClassDecl, ClassDecl->getLocation(), Name,
+ = CXXMethodDecl::Create(Context, ClassDecl, NameInfo,
Context.getFunctionType(RetType, &ArgType, 1,
false, 0,
ExceptSpec.hasExceptionSpecification(),
@@ -4757,7 +4893,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
ExceptSpec.data(),
FunctionType::ExtInfo()),
/*TInfo=*/0, /*isStatic=*/false,
- /*StorageClassAsWritten=*/FunctionDecl::None,
+ /*StorageClassAsWritten=*/SC_None,
/*isInline=*/true);
CopyAssignment->setAccess(AS_public);
CopyAssignment->setImplicit();
@@ -4769,8 +4905,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
ClassDecl->getLocation(),
/*Id=*/0,
ArgType, /*TInfo=*/0,
- VarDecl::None,
- VarDecl::None, 0);
+ SC_None,
+ SC_None, 0);
CopyAssignment->setParams(&FromParam, 1);
// Note that we have added this copy-assignment operator.
@@ -4814,7 +4950,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// which they were declared in the class definition.
// The statements that form the synthesized function body.
- ASTOwningVector<&ActionBase::DeleteStmt> Statements(*this);
+ ASTOwningVector<Stmt*> Statements(*this);
// The parameter for the "other" object, which we are copying from.
ParmVarDecl *Other = CopyAssignOperator->getParamDecl(0);
@@ -4854,30 +4990,32 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
continue;
}
+ CXXCastPath BasePath;
+ BasePath.push_back(Base);
+
// Construct the "from" expression, which is an implicit cast to the
// appropriately-qualified base type.
Expr *From = OtherRef->Retain();
ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
- CastExpr::CK_UncheckedDerivedToBase, /*isLvalue=*/true,
- CXXBaseSpecifierArray(Base));
+ CK_UncheckedDerivedToBase,
+ VK_LValue, &BasePath);
// Dereference "this".
- OwningExprResult To = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
- Owned(This->Retain()));
+ ExprResult To = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
// Implicitly cast "this" to the appropriately-qualified base type.
Expr *ToE = To.takeAs<Expr>();
ImpCastExprToType(ToE,
Context.getCVRQualifiedType(BaseType,
CopyAssignOperator->getTypeQualifiers()),
- CastExpr::CK_UncheckedDerivedToBase,
- /*isLvalue=*/true, CXXBaseSpecifierArray(Base));
+ CK_UncheckedDerivedToBase,
+ VK_LValue, &BasePath);
To = Owned(ToE);
// Build the copy.
- OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
- move(To), Owned(From),
- /*CopyingBaseSubobject=*/true);
+ StmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
+ To.get(), From,
+ /*CopyingBaseSubobject=*/true);
if (Copy.isInvalid()) {
Diag(CurrentLocation, diag::note_member_synthesized_at)
<< CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
@@ -4934,12 +5072,10 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
LookupMemberName);
MemberLookup.addDecl(*Field);
MemberLookup.resolveKind();
- OwningExprResult From = BuildMemberReferenceExpr(Owned(OtherRef->Retain()),
- OtherRefType,
+ ExprResult From = BuildMemberReferenceExpr(OtherRef, OtherRefType,
Loc, /*IsArrow=*/false,
SS, 0, MemberLookup, 0);
- OwningExprResult To = BuildMemberReferenceExpr(Owned(This->Retain()),
- This->getType(),
+ ExprResult To = BuildMemberReferenceExpr(This, This->getType(),
Loc, /*IsArrow=*/true,
SS, 0, MemberLookup, 0);
assert(!From.isInvalid() && "Implicit field reference cannot fail");
@@ -4967,8 +5103,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
}
// Take the address of the field references for "from" and "to".
- From = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(From));
- To = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(To));
+ From = CreateBuiltinUnaryOp(Loc, UO_AddrOf, From.get());
+ To = CreateBuiltinUnaryOp(Loc, UO_AddrOf, To.get());
bool NeedsCollectableMemCpy =
(BaseType->isRecordType() &&
@@ -5016,22 +5152,22 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
assert(BuiltinMemCpyRef && "Builtin reference cannot fail");
}
- ASTOwningVector<&ActionBase::DeleteExpr> CallArgs(*this);
+ ASTOwningVector<Expr*> CallArgs(*this);
CallArgs.push_back(To.takeAs<Expr>());
CallArgs.push_back(From.takeAs<Expr>());
- CallArgs.push_back(new (Context) IntegerLiteral(Size, SizeType, Loc));
+ CallArgs.push_back(IntegerLiteral::Create(Context, Size, SizeType, Loc));
llvm::SmallVector<SourceLocation, 4> Commas; // FIXME: Silly
Commas.push_back(Loc);
Commas.push_back(Loc);
- OwningExprResult Call = ExprError();
+ ExprResult Call = ExprError();
if (NeedsCollectableMemCpy)
Call = ActOnCallExpr(/*Scope=*/0,
- Owned(CollectableMemCpyRef->Retain()),
+ CollectableMemCpyRef,
Loc, move_arg(CallArgs),
Commas.data(), Loc);
else
Call = ActOnCallExpr(/*Scope=*/0,
- Owned(BuiltinMemCpyRef->Retain()),
+ BuiltinMemCpyRef,
Loc, move_arg(CallArgs),
Commas.data(), Loc);
@@ -5041,8 +5177,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
}
// Build the copy of this field.
- OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType,
- move(To), move(From),
+ StmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType,
+ To.get(), From.get(),
/*CopyingBaseSubobject=*/false);
if (Copy.isInvalid()) {
Diag(CurrentLocation, diag::note_member_synthesized_at)
@@ -5057,10 +5193,9 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
if (!Invalid) {
// Add a "return *this;"
- OwningExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
- Owned(This->Retain()));
+ ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
- OwningStmtResult Return = ActOnReturnStmt(Loc, move(ThisObj));
+ StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get());
if (Return.isInvalid())
Invalid = true;
else {
@@ -5079,7 +5214,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
return;
}
- OwningStmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
+ StmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
/*isStmtExpr=*/false);
assert(!Body.isInvalid() && "Compound statement creation cannot fail");
CopyAssignOperator->setBody(Body.takeAs<Stmt>());
@@ -5220,9 +5355,9 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ClassType));
+ DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
CXXConstructorDecl *CopyConstructor
- = CXXConstructorDecl::Create(Context, ClassDecl,
- ClassDecl->getLocation(), Name,
+ = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
Context.getFunctionType(Context.VoidTy,
&ArgType, 1,
false, 0,
@@ -5248,8 +5383,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
ClassDecl->getLocation(),
/*IdentifierInfo=*/0,
ArgType, /*TInfo=*/0,
- VarDecl::None,
- VarDecl::None, 0);
+ SC_None,
+ SC_None, 0);
CopyConstructor->setParams(&FromParam, 1);
if (Scope *S = getScopeForContext(ClassDecl))
PushOnScopeChains(CopyConstructor, S, false);
@@ -5288,12 +5423,12 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
CopyConstructor->setUsed();
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- CXXConstructExpr::ConstructionKind ConstructKind) {
+ unsigned ConstructKind) {
bool Elidable = false;
// C++0x [class.copy]p34:
@@ -5309,6 +5444,7 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
Elidable = SubExpr->isTemporaryObject() &&
+ ConstructKind == CXXConstructExpr::CK_Complete &&
Context.hasSameUnqualifiedType(SubExpr->getType(),
Context.getTypeDeclType(Constructor->getParent()));
}
@@ -5320,27 +5456,28 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
-Sema::OwningExprResult
+ExprResult
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- CXXConstructExpr::ConstructionKind ConstructKind) {
+ unsigned ConstructKind) {
unsigned NumExprs = ExprArgs.size();
Expr **Exprs = (Expr **)ExprArgs.release();
MarkDeclarationReferenced(ConstructLoc, Constructor);
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
- RequiresZeroInit, ConstructKind));
+ RequiresZeroInit,
+ static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind)));
}
bool Sema::InitializeVarWithConstructor(VarDecl *VD,
CXXConstructorDecl *Constructor,
MultiExprArg Exprs) {
- OwningExprResult TempResult =
+ ExprResult TempResult =
BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
- move(Exprs));
+ move(Exprs), false, CXXConstructExpr::CK_Complete);
if (TempResult.isInvalid())
return true;
@@ -5362,19 +5499,21 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
PDiag(diag::err_access_dtor_var)
<< VD->getDeclName()
<< VD->getType());
+
+ if (!VD->isInvalidDecl() && VD->hasGlobalStorage())
+ Diag(VD->getLocation(), diag::warn_global_destructor);
}
}
/// AddCXXDirectInitializerToDecl - This action is called immediately after
/// ActOnDeclarator, when a C++ direct initializer is present.
/// e.g: "int x(1);"
-void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
SourceLocation LParenLoc,
MultiExprArg Exprs,
SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
assert(Exprs.size() != 0 && Exprs.get() && "missing expressions");
- Decl *RealDecl = Dcl.getAs<Decl>();
// If there is no declaration, there was an error parsing it. Just ignore
// the initializer.
@@ -5402,9 +5541,6 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
// The form of initialization (using parentheses or '=') is generally
// insignificant, but does matter when the entity being initialized has a
// class type.
- QualType DeclInitType = VDecl->getType();
- if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
- DeclInitType = Context.getBaseElementType(Array);
if (!VDecl->getType()->isDependentType() &&
RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
@@ -5428,6 +5564,25 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
return;
}
+ // C++ [class.static.data]p4
+ // If a static data member is of const integral or const
+ // enumeration type, its declaration in the class definition can
+ // specify a constant-initializer which shall be an integral
+ // constant expression (5.19). In that case, the member can appear
+ // in integral constant expressions. The member shall still be
+ // defined in a namespace scope if it is used in the program and the
+ // namespace scope definition shall not contain an initializer.
+ //
+ // We already performed a redefinition check above, but for static
+ // data members we also need to check whether there was an in-class
+ // declaration with an initializer.
+ const VarDecl* PrevInit = 0;
+ if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+ Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+ Diag(PrevInit->getLocation(), diag::note_previous_definition);
+ return;
+ }
+
// If either the declaration has a dependent type or if any of the
// expressions is type-dependent, we represent the initialization
// via a ParenListExpr for later use during template instantiation.
@@ -5454,17 +5609,25 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind,
- (Expr**)Exprs.get(), Exprs.size());
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
+ Exprs.get(), Exprs.size());
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
return;
}
- Result = MaybeCreateCXXExprWithTemporaries(move(Result));
+ Result = MaybeCreateCXXExprWithTemporaries(Result.get());
VDecl->setInit(Result.takeAs<Expr>());
VDecl->setCXXDirectInitializer(true);
+ if (!VDecl->isInvalidDecl() &&
+ !VDecl->getDeclContext()->isDependentContext() &&
+ VDecl->hasGlobalStorage() &&
+ !VDecl->getInit()->isConstantInitializer(Context,
+ VDecl->getType()->isReferenceType()))
+ Diag(VDecl->getLocation(), diag::warn_global_constructor)
+ << VDecl->getInit()->getSourceRange();
+
if (const RecordType *Record = VDecl->getType()->getAs<RecordType>())
FinalizeVarWithDestructor(VDecl, Record);
}
@@ -5478,7 +5641,7 @@ bool
Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
MultiExprArg ArgsPtr,
SourceLocation Loc,
- ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs) {
+ ASTOwningVector<Expr*> &ConvertedArgs) {
// FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall.
unsigned NumArgs = ArgsPtr.size();
Expr **Args = (Expr **)ArgsPtr.get();
@@ -5508,7 +5671,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
static inline bool
CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef,
const FunctionDecl *FnDecl) {
- const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext();
+ const DeclContext *DC = FnDecl->getDeclContext()->getRedeclContext();
if (isa<NamespaceDecl>(DC)) {
return SemaRef.Diag(FnDecl->getLocation(),
diag::err_operator_new_delete_declared_in_namespace)
@@ -5516,7 +5679,7 @@ CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef,
}
if (isa<TranslationUnitDecl>(DC) &&
- FnDecl->getStorageClass() == FunctionDecl::Static) {
+ FnDecl->getStorageClass() == SC_Static) {
return SemaRef.Diag(FnDecl->getLocation(),
diag::err_operator_new_delete_declared_static)
<< FnDecl->getDeclName();
@@ -5622,18 +5785,6 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
diag::err_operator_delete_param_type))
return true;
- QualType FirstParamType = FnDecl->getParamDecl(0)->getType();
- if (FirstParamType->isDependentType())
- return SemaRef.Diag(FnDecl->getLocation(),
- diag::err_operator_delete_dependent_param_type)
- << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
-
- if (SemaRef.Context.getCanonicalType(FirstParamType) !=
- SemaRef.Context.VoidPtrTy)
- return SemaRef.Diag(FnDecl->getLocation(),
- diag::err_operator_delete_param_type)
- << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
-
return false;
}
@@ -5891,7 +6042,7 @@ FinishedParams:
/// by Lang/StrSize. LBraceLoc, if valid, provides the location of
/// the '{' brace. Otherwise, this linkage specification does not
/// have any braces.
-Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
+Decl *Sema::ActOnStartLinkageSpecification(Scope *S,
SourceLocation ExternLoc,
SourceLocation LangLoc,
llvm::StringRef Lang,
@@ -5903,7 +6054,7 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
Language = LinkageSpecDecl::lang_cxx;
else {
Diag(LangLoc, diag::err_bad_language);
- return DeclPtrTy();
+ return 0;
}
// FIXME: Add all the various semantics of linkage specifications
@@ -5913,15 +6064,15 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
LBraceLoc.isValid());
CurContext->addDecl(D);
PushDeclContext(S, D);
- return DeclPtrTy::make(D);
+ return D;
}
-/// ActOnFinishLinkageSpecification - Completely the definition of
+/// ActOnFinishLinkageSpecification - Complete the definition of
/// the C++ linkage specification LinkageSpec. If RBraceLoc is
/// valid, it's the position of the closing '}' brace in a linkage
/// specification that uses braces.
-Sema::DeclPtrTy Sema::ActOnFinishLinkageSpecification(Scope *S,
- DeclPtrTy LinkageSpec,
+Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
+ Decl *LinkageSpec,
SourceLocation RBraceLoc) {
if (LinkageSpec)
PopDeclContext();
@@ -5983,9 +6134,30 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
AbstractVariableType))
Invalid = true;
+ // Only the non-fragile NeXT runtime currently supports C++ catches
+ // of ObjC types, and no runtime supports catching ObjC types by value.
+ if (!Invalid && getLangOptions().ObjC1) {
+ QualType T = ExDeclType;
+ if (const ReferenceType *RT = T->getAs<ReferenceType>())
+ T = RT->getPointeeType();
+
+ if (T->isObjCObjectType()) {
+ Diag(Loc, diag::err_objc_object_catch);
+ Invalid = true;
+ } else if (T->isObjCObjectPointerType()) {
+ if (!getLangOptions().NeXTRuntime) {
+ Diag(Loc, diag::err_objc_pointer_cxx_catch_gnu);
+ Invalid = true;
+ } else if (!getLangOptions().ObjCNonFragileABI) {
+ Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
+ Invalid = true;
+ }
+ }
+ }
+
VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
- Name, ExDeclType, TInfo, VarDecl::None,
- VarDecl::None);
+ Name, ExDeclType, TInfo, SC_None,
+ SC_None);
ExDecl->setExceptionVariable(true);
if (!Invalid) {
@@ -6005,8 +6177,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
InitializationKind Kind = InitializationKind::CreateCopy(Loc,
SourceLocation());
InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&ExDeclRef, 1));
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &ExDeclRef, 1));
if (Result.isInvalid())
Invalid = true;
else
@@ -6022,7 +6194,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
/// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch
/// handler.
-Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType ExDeclType = TInfo->getType();
@@ -6033,7 +6205,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
ForRedeclaration)) {
// The scope should be freshly made just for us. There is just no way
// it contains any previous declaration.
- assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
+ assert(!S->isDeclScope(PrevDecl));
if (PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@@ -6061,22 +6233,20 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
CurContext->addDecl(ExDecl);
ProcessDeclAttributes(S, ExDecl, D);
- return DeclPtrTy::make(ExDecl);
+ return ExDecl;
}
-Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
- ExprArg assertexpr,
- ExprArg assertmessageexpr) {
- Expr *AssertExpr = (Expr *)assertexpr.get();
- StringLiteral *AssertMessage =
- cast<StringLiteral>((Expr *)assertmessageexpr.get());
+Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+ Expr *AssertExpr,
+ Expr *AssertMessageExpr_) {
+ StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
llvm::APSInt Value(32);
if (!AssertExpr->isIntegerConstantExpr(Value, Context)) {
Diag(AssertLoc, diag::err_static_assert_expression_is_not_constant) <<
AssertExpr->getSourceRange();
- return DeclPtrTy();
+ return 0;
}
if (Value == 0) {
@@ -6085,13 +6255,11 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
}
}
- assertexpr.release();
- assertmessageexpr.release();
Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
AssertExpr, AssertMessage);
CurContext->addDecl(Decl);
- return DeclPtrTy::make(Decl);
+ return Decl;
}
/// \brief Perform semantic analysis of the given friend type declaration.
@@ -6167,7 +6335,7 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation FriendLoc,
/// We permit this as a special case; if there are any template
/// parameters present at all, require proper matching, i.e.
/// template <> template <class T> friend class A<int>::B;
-Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
MultiTemplateParamsArg TempParams) {
SourceLocation Loc = DS.getSourceRange().getBegin();
@@ -6181,7 +6349,7 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S);
QualType T = TSI->getType();
if (TheDeclarator.isInvalidType())
- return DeclPtrTy();
+ return 0;
// This is definitely an error in C++98. It's probably meant to
// be forbidden in C++0x, too, but the specification is just
@@ -6200,7 +6368,7 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
if (TempParams.size() && !T->isElaboratedTypeSpecifier()) {
Diag(Loc, diag::err_tagless_friend_type_template)
<< DS.getSourceRange();
- return DeclPtrTy();
+ return 0;
}
// C++98 [class.friend]p1: A friend of a class is a function
@@ -6225,18 +6393,17 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
D = CheckFriendTypeDecl(DS.getFriendSpecLoc(), TSI);
if (!D)
- return DeclPtrTy();
+ return 0;
D->setAccess(AS_public);
CurContext->addDecl(D);
- return DeclPtrTy::make(D);
+ return D;
}
-Sema::DeclPtrTy
-Sema::ActOnFriendFunctionDecl(Scope *S,
- Declarator &D,
- bool IsDefinition,
+Decl *Sema::ActOnFriendFunctionDecl(Scope *S,
+ Declarator &D,
+ bool IsDefinition,
MultiTemplateParamsArg TemplateParams) {
const DeclSpec &DS = D.getDeclSpec();
@@ -6262,7 +6429,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// It might be worthwhile to try to recover by creating an
// appropriate declaration.
- return DeclPtrTy();
+ return 0;
}
// C++ [namespace.memdef]p3
@@ -6281,7 +6448,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// namespace scope are not considered.
CXXScopeSpec &ScopeQual = D.getCXXScopeSpec();
- DeclarationName Name = GetNameForDeclarator(D);
+ DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+ DeclarationName Name = NameInfo.getName();
assert(Name);
// The context we found the declaration in, or in which we should
@@ -6291,14 +6459,14 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// FIXME: handle local classes
// Recover from invalid scope qualifiers as if they just weren't there.
- LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
ForRedeclaration);
if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
DC = computeDeclContext(ScopeQual);
// FIXME: handle dependent contexts
- if (!DC) return DeclPtrTy();
- if (RequireCompleteDeclContext(ScopeQual, DC)) return DeclPtrTy();
+ if (!DC) return 0;
+ if (RequireCompleteDeclContext(ScopeQual, DC)) return 0;
LookupQualifiedName(Previous, DC);
@@ -6308,7 +6476,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
LookupResult::Filter F = Previous.makeFilter();
while (F.hasNext()) {
NamedDecl *D = F.next();
- if (!D->getDeclContext()->getLookupContext()->Equals(DC))
+ if (!DC->InEnclosingNamespaceSetOf(
+ D->getDeclContext()->getRedeclContext()))
F.erase();
}
F.done();
@@ -6316,7 +6485,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
if (Previous.empty()) {
D.setInvalidType();
Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
- return DeclPtrTy();
+ return 0;
}
// C++ [class.friend]p1: A friend of a class is a function or
@@ -6368,7 +6537,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
Diag(Loc, diag::err_introducing_special_friend) <<
(D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
- return DeclPtrTy();
+ return 0;
}
}
@@ -6377,7 +6546,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
move(TemplateParams),
IsDefinition,
Redeclaration);
- if (!ND) return DeclPtrTy();
+ if (!ND) return 0;
assert(ND->getDeclContext() == DC);
assert(ND->getLexicalDeclContext() == CurContext);
@@ -6389,7 +6558,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// Also update the scope-based lookup if the target context's
// lookup context is in lexical scope.
if (!CurContext->isDependentContext()) {
- DC = DC->getLookupContext();
+ DC = DC->getRedeclContext();
DC->makeDeclVisibleInContext(ND, /* Recoverable=*/ false);
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
PushOnScopeChains(ND, EnclosingScope, /*AddToContext=*/ false);
@@ -6401,13 +6570,12 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
FrD->setAccess(AS_public);
CurContext->addDecl(FrD);
- return DeclPtrTy::make(ND);
+ return ND;
}
-void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
- AdjustDeclIfTemplate(dcl);
+void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
+ AdjustDeclIfTemplate(Dcl);
- Decl *Dcl = dcl.getAs<Decl>();
FunctionDecl *Fn = dyn_cast<FunctionDecl>(Dcl);
if (!Fn) {
Diag(DelLoc, diag::err_deleted_non_function);
@@ -6575,9 +6743,8 @@ bool Sema::CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange) {
/// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
/// static data member of class X, names should be looked up in the scope of
/// class X.
-void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
// If there is no declaration, there was an error parsing it.
- Decl *D = Dcl.getAs<Decl>();
if (D == 0) return;
// We should only get called for declarations with scope specifiers, like:
@@ -6587,10 +6754,9 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
}
/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
-/// initializer for the out-of-line declaration 'Dcl'.
-void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+/// initializer for the out-of-line declaration 'D'.
+void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
// If there is no declaration, there was an error parsing it.
- Decl *D = Dcl.getAs<Decl>();
if (D == 0) return;
assert(D->isOutOfLine());
@@ -6600,8 +6766,7 @@ void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
/// C++ if/switch/while/for statement.
/// e.g: "if (int x = f()) {...}"
-Action::DeclResult
-Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+DeclResult Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
// C++ 6.4p2:
// The declarator shall not specify a function or an array.
// The type-specifier-seq shall not contain typedef and shall not declare a
@@ -6624,12 +6789,10 @@ Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition);
}
- DeclPtrTy Dcl = ActOnDeclarator(S, D);
+ Decl *Dcl = ActOnDeclarator(S, D);
if (!Dcl)
return DeclResult();
- VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
- VD->setDeclaredInCondition(true);
return Dcl;
}
@@ -6775,8 +6938,6 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- if (i->isVirtual())
- continue;
if (Base->getNumVBases() == 0)
continue;
MarkVirtualMembersReferenced(Loc, Base);
@@ -6788,7 +6949,7 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
if (!getLangOptions().CPlusPlus)
return;
- if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+ if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
CollectIvarsToConstructOrDestruct(OID, ivars);
if (ivars.empty())
@@ -6805,10 +6966,9 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
InitializationKind::CreateDefault(ObjCImplementation->getLocation());
InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0);
- Sema::OwningExprResult MemberInit =
- InitSeq.Perform(*this, InitEntity, InitKind,
- Sema::MultiExprArg(*this, 0, 0));
- MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+ ExprResult MemberInit =
+ InitSeq.Perform(*this, InitEntity, InitKind, MultiExprArg());
+ MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
// Note, MemberInit could actually come back empty if no initialization
// is required (e.g., because it would call a trivial default constructor)
if (!MemberInit.get() || MemberInit.isInvalid())
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 21aeb59a0886..a6902a3e391c 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -11,20 +11,24 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "llvm/ADT/DenseSet.h"
+
using namespace clang;
/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
/// and user declared, in the method definition's AST.
-void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
assert(getCurMethodDecl() == 0 && "Method parsing confused");
- ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
+ ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
// If we don't have a valid method decl, simply return.
if (!MDecl)
@@ -32,10 +36,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
// Allow the rest of sema to find private method decl implementations.
if (MDecl->isInstanceMethod())
- AddInstanceMethodToGlobalPool(MDecl);
+ AddInstanceMethodToGlobalPool(MDecl, true);
else
- AddFactoryMethodToGlobalPool(MDecl);
-
+ AddFactoryMethodToGlobalPool(MDecl, true);
+
// Allow all of Sema to see that we are entering a method definition.
PushDeclContext(FnBodyScope, MDecl);
PushFunctionScope();
@@ -56,11 +60,11 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
PushOnScopeChains(*PI, FnBodyScope);
}
-Sema::DeclPtrTy Sema::
+Decl *Sema::
ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperName, SourceLocation SuperLoc,
- const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
+ Decl * const *ProtoRefs, unsigned NumProtoRefs,
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc, AttributeList *AttrList) {
assert(ClassName && "Missing class identifier");
@@ -84,11 +88,14 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
// Return the previous class interface.
// FIXME: don't leak the objects passed in!
- return DeclPtrTy::make(IDecl);
+ return IDecl;
} else {
IDecl->setLocation(AtInterfaceLoc);
IDecl->setForwardDecl(false);
IDecl->setClassLoc(ClassLoc);
+ // If the forward decl was in a PCH, we need to write it again in a
+ // dependent AST file.
+ IDecl->setChangedSinceDeserialization(true);
// Since this ObjCInterfaceDecl was created by a forward declaration,
// we now add it to the DeclContext since it wasn't added before
@@ -176,7 +183,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IDecl->setLocEnd(ClassLoc);
}
- /// Check then save referenced protocols.
+ // Check then save referenced protocols.
if (NumProtoRefs) {
IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
ProtoLocs, Context);
@@ -184,16 +191,16 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
}
CheckObjCDeclScope(IDecl);
- return DeclPtrTy::make(IDecl);
+ return IDecl;
}
/// ActOnCompatiblityAlias - this action is called after complete parsing of
/// @compatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
- IdentifierInfo *AliasName,
- SourceLocation AliasLocation,
- IdentifierInfo *ClassName,
- SourceLocation ClassLocation) {
+Decl *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
+ IdentifierInfo *AliasName,
+ SourceLocation AliasLocation,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLocation) {
// Look for previous declaration of alias name
NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
LookupOrdinaryName, ForRedeclaration);
@@ -203,7 +210,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
else
Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
Diag(ADecl->getLocation(), diag::note_previous_declaration);
- return DeclPtrTy();
+ return 0;
}
// Check for class declaration
NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
@@ -223,7 +230,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
if (CDeclU)
Diag(CDeclU->getLocation(), diag::note_previous_declaration);
- return DeclPtrTy();
+ return 0;
}
// Everything checked out, instantiate a new alias declaration AST.
@@ -233,7 +240,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
if (!CheckObjCDeclScope(AliasDecl))
PushOnScopeChains(AliasDecl, TUScope);
- return DeclPtrTy::make(AliasDecl);
+ return AliasDecl;
}
void Sema::CheckForwardProtocolDeclarationForCircularDependency(
@@ -255,11 +262,11 @@ void Sema::CheckForwardProtocolDeclarationForCircularDependency(
}
}
-Sema::DeclPtrTy
+Decl *
Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName,
SourceLocation ProtocolLoc,
- const DeclPtrTy *ProtoRefs,
+ Decl * const *ProtoRefs,
unsigned NumProtoRefs,
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
@@ -274,17 +281,19 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
Diag(PDecl->getLocation(), diag::note_previous_definition);
// Just return the protocol we already had.
// FIXME: don't leak the objects passed in!
- return DeclPtrTy::make(PDecl);
+ return PDecl;
}
ObjCList<ObjCProtocolDecl> PList;
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
CheckForwardProtocolDeclarationForCircularDependency(
ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
- PList.Destroy(Context);
// Make sure the cached decl gets a valid start location.
PDecl->setLocation(AtProtoInterfaceLoc);
PDecl->setForwardDecl(false);
+ CurContext->addDecl(PDecl);
+ // Repeat in dependent AST files.
+ PDecl->setChangedSinceDeserialization(true);
} else {
PDecl = ObjCProtocolDecl::Create(Context, CurContext,
AtProtoInterfaceLoc,ProtocolName);
@@ -301,7 +310,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
}
CheckObjCDeclScope(PDecl);
- return DeclPtrTy::make(PDecl);
+ return PDecl;
}
/// FindProtocolDeclaration - This routine looks up protocols and
@@ -311,7 +320,7 @@ void
Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
const IdentifierLocPair *ProtocolId,
unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
+ llvm::SmallVectorImpl<Decl *> &Protocols) {
for (unsigned i = 0; i != NumProtocols; ++i) {
ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
ProtocolId[i].second);
@@ -340,7 +349,7 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
if (WarnOnDeclarations && PDecl->isForwardDecl())
Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
<< ProtocolId[i].first;
- Protocols.push_back(DeclPtrTy::make(PDecl));
+ Protocols.push_back(PDecl);
}
}
@@ -374,7 +383,7 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
}
/// ActOnForwardProtocolDeclaration - Handle @protocol foo;
-Action::DeclPtrTy
+Decl *
Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
const IdentifierLocPair *IdentList,
unsigned NumElts,
@@ -385,13 +394,18 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
for (unsigned i = 0; i != NumElts; ++i) {
IdentifierInfo *Ident = IdentList[i].first;
ObjCProtocolDecl *PDecl = LookupProtocol(Ident, IdentList[i].second);
+ bool isNew = false;
if (PDecl == 0) { // Not already seen?
PDecl = ObjCProtocolDecl::Create(Context, CurContext,
IdentList[i].second, Ident);
- PushOnScopeChains(PDecl, TUScope);
+ PushOnScopeChains(PDecl, TUScope, false);
+ isNew = true;
}
- if (attrList)
+ if (attrList) {
ProcessDeclAttributeList(TUScope, PDecl, attrList);
+ if (!isNew)
+ PDecl->setChangedSinceDeserialization(true);
+ }
Protocols.push_back(PDecl);
ProtoLocs.push_back(IdentList[i].second);
}
@@ -402,15 +416,15 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
ProtoLocs.data());
CurContext->addDecl(PDecl);
CheckObjCDeclScope(PDecl);
- return DeclPtrTy::make(PDecl);
+ return PDecl;
}
-Sema::DeclPtrTy Sema::
+Decl *Sema::
ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *CategoryName,
SourceLocation CategoryLoc,
- const DeclPtrTy *ProtoRefs,
+ Decl * const *ProtoRefs,
unsigned NumProtoRefs,
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc) {
@@ -426,7 +440,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
ClassLoc, CategoryLoc, CategoryName);
CDecl->setInvalidDecl();
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
- return DeclPtrTy::make(CDecl);
+ return CDecl;
}
if (!CategoryName && IDecl->getImplementation()) {
@@ -471,18 +485,17 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
// Protocols in the class extension belong to the class.
if (CDecl->IsClassExtension())
IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs,
- NumProtoRefs, ProtoLocs,
- Context);
+ NumProtoRefs, Context);
}
CheckObjCDeclScope(CDecl);
- return DeclPtrTy::make(CDecl);
+ return CDecl;
}
/// ActOnStartCategoryImplementation - Perform semantic checks on the
/// category implementation declaration and build an ObjCCategoryImplDecl
/// object.
-Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
+Decl *Sema::ActOnStartCategoryImplementation(
SourceLocation AtCatImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *CatName, SourceLocation CatLoc) {
@@ -523,10 +536,10 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
}
CheckObjCDeclScope(CDecl);
- return DeclPtrTy::make(CDecl);
+ return CDecl;
}
-Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
+Decl *Sema::ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperClassname,
@@ -617,7 +630,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
IDecl, SDecl);
if (CheckObjCDeclScope(IMPDecl))
- return DeclPtrTy::make(IMPDecl);
+ return IMPDecl;
// Check that there is no duplicate implementation of this class.
if (IDecl->getImplementation()) {
@@ -629,7 +642,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
IDecl->setImplementation(IMPDecl);
PushOnScopeChains(IMPDecl, TUScope);
}
- return DeclPtrTy::make(IMPDecl);
+ return IMPDecl;
}
void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -910,8 +923,9 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
}
if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
// Check for any implementation of a methods declared in protocol.
- for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
- E = I->protocol_end(); PI != E; ++PI)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = I->all_referenced_protocol_begin(),
+ E = I->all_referenced_protocol_end(); PI != E; ++PI)
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
(*PI), IncompleteImpl, false);
@@ -957,8 +971,9 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
// implemented in the implementation class.
if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
- for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
- E = I->protocol_end(); PI != E; ++PI)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = I->all_referenced_protocol_begin(),
+ E = I->all_referenced_protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
InsMap, ClsMap, I);
// Check class extensions (unnamed categories)
@@ -992,7 +1007,7 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
}
/// ActOnForwardClassDeclaration -
-Action::DeclPtrTy
+Decl *
Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
SourceLocation *IdentLocs,
@@ -1053,7 +1068,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
Interfaces.size());
CurContext->addDecl(CDecl);
CheckObjCDeclScope(CDecl);
- return DeclPtrTy::make(CDecl);
+ return CDecl;
}
@@ -1062,13 +1077,14 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
/// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
const ObjCMethodDecl *PrevMethod,
- bool matchBasedOnSizeAndAlignment) {
+ bool matchBasedOnSizeAndAlignment,
+ bool matchBasedOnStrictEqulity) {
QualType T1 = Context.getCanonicalType(Method->getResultType());
QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
if (T1 != T2) {
// The result types are different.
- if (!matchBasedOnSizeAndAlignment)
+ if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
return false;
// Incomplete types don't have a size and alignment.
if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1088,7 +1104,7 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
T2 = Context.getCanonicalType((*PrevI)->getType());
if (T1 != T2) {
// The result types are different.
- if (!matchBasedOnSizeAndAlignment)
+ if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
return false;
// Incomplete types don't have a size and alignment.
if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1101,47 +1117,34 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
return true;
}
-/// \brief Read the contents of the instance and factory method pools
-/// for a given selector from external storage.
+/// \brief Read the contents of the method pool for a given selector from
+/// external storage.
///
-/// This routine should only be called once, when neither the instance
-/// nor the factory method pool has an entry for this selector.
-Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
- bool isInstance) {
+/// This routine should only be called once, when the method pool has no entry
+/// for this selector.
+Sema::GlobalMethodPool::iterator Sema::ReadMethodPool(Selector Sel) {
assert(ExternalSource && "We need an external AST source");
- assert(InstanceMethodPool.find(Sel) == InstanceMethodPool.end() &&
- "Selector data already loaded into the instance method pool");
- assert(FactoryMethodPool.find(Sel) == FactoryMethodPool.end() &&
- "Selector data already loaded into the factory method pool");
+ assert(MethodPool.find(Sel) == MethodPool.end() &&
+ "Selector data already loaded into the method pool");
// Read the method list from the external source.
- std::pair<ObjCMethodList, ObjCMethodList> Methods
- = ExternalSource->ReadMethodPool(Sel);
+ GlobalMethods Methods = ExternalSource->ReadMethodPool(Sel);
- if (isInstance) {
- if (Methods.second.Method)
- FactoryMethodPool[Sel] = Methods.second;
- return InstanceMethodPool.insert(std::make_pair(Sel, Methods.first)).first;
- }
-
- if (Methods.first.Method)
- InstanceMethodPool[Sel] = Methods.first;
-
- return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
+ return MethodPool.insert(std::make_pair(Sel, Methods)).first;
}
-void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
- llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
- = InstanceMethodPool.find(Method->getSelector());
- if (Pos == InstanceMethodPool.end()) {
- if (ExternalSource && !FactoryMethodPool.count(Method->getSelector()))
- Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/true);
+void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
+ bool instance) {
+ GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
+ if (Pos == MethodPool.end()) {
+ if (ExternalSource)
+ Pos = ReadMethodPool(Method->getSelector());
else
- Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
- ObjCMethodList())).first;
+ Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
+ GlobalMethods())).first;
}
-
- ObjCMethodList &Entry = Pos->second;
+ Method->setDefined(impl);
+ ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
if (Entry.Method == 0) {
// Haven't seen a method with this selector name yet - add it.
Entry.Method = Method;
@@ -1152,8 +1155,10 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
// We've seen a method with this name, see if we have already seen this type
// signature.
for (ObjCMethodList *List = &Entry; List; List = List->Next)
- if (MatchTwoMethodDeclarations(Method, List->Method))
+ if (MatchTwoMethodDeclarations(Method, List->Method)) {
+ List->Method->setDefined(impl);
return;
+ }
// We have a new signature for an existing method - add it.
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
@@ -1161,102 +1166,65 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
}
-// FIXME: Finish implementing -Wno-strict-selector-match.
-ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
- SourceRange R,
- bool warn) {
- llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
- = InstanceMethodPool.find(Sel);
- if (Pos == InstanceMethodPool.end()) {
- if (ExternalSource && !FactoryMethodPool.count(Sel))
- Pos = ReadMethodPool(Sel, /*isInstance=*/true);
+ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
+ bool receiverIdOrClass,
+ bool warn, bool instance) {
+ GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+ if (Pos == MethodPool.end()) {
+ if (ExternalSource)
+ Pos = ReadMethodPool(Sel);
else
return 0;
}
- ObjCMethodList &MethList = Pos->second;
- bool issueWarning = false;
+ ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
- if (MethList.Method && MethList.Next) {
- for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
- // This checks if the methods differ by size & alignment.
- if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
- issueWarning = warn;
- }
- if (issueWarning && (MethList.Method && MethList.Next)) {
- Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
- Diag(MethList.Method->getLocStart(), diag::note_using)
- << MethList.Method->getSourceRange();
- for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
- Diag(Next->Method->getLocStart(), diag::note_also_found)
- << Next->Method->getSourceRange();
- }
- return MethList.Method;
-}
+ bool strictSelectorMatch = receiverIdOrClass && warn &&
+ (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl) !=
+ Diagnostic::Ignored);
+ if (warn && MethList.Method && MethList.Next) {
+ bool issueWarning = false;
+ if (strictSelectorMatch)
+ for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) {
+ // This checks if the methods differ in type mismatch.
+ if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, false, true))
+ issueWarning = true;
+ }
-void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
- llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
- = FactoryMethodPool.find(Method->getSelector());
- if (Pos == FactoryMethodPool.end()) {
- if (ExternalSource && !InstanceMethodPool.count(Method->getSelector()))
- Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/false);
- else
- Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
- ObjCMethodList())).first;
- }
+ if (!issueWarning)
+ for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) {
+ // This checks if the methods differ by size & alignment.
+ if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
+ issueWarning = true;
+ }
- ObjCMethodList &FirstMethod = Pos->second;
- if (!FirstMethod.Method) {
- // Haven't seen a method with this selector name yet - add it.
- FirstMethod.Method = Method;
- FirstMethod.Next = 0;
- } else {
- // We've seen a method with this name, now check the type signature(s).
- bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-
- for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
- Next = Next->Next)
- match = MatchTwoMethodDeclarations(Method, Next->Method);
-
- if (!match) {
- // We have a new signature for an existing method - add it.
- // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
- ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
- ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next);
- FirstMethod.Next = OMI;
+ if (issueWarning) {
+ if (strictSelectorMatch)
+ Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
+ else
+ Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
+ Diag(MethList.Method->getLocStart(), diag::note_using)
+ << MethList.Method->getSourceRange();
+ for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+ Diag(Next->Method->getLocStart(), diag::note_also_found)
+ << Next->Method->getSourceRange();
}
}
+ return MethList.Method;
}
-ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
- SourceRange R) {
- llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
- = FactoryMethodPool.find(Sel);
- if (Pos == FactoryMethodPool.end()) {
- if (ExternalSource && !InstanceMethodPool.count(Sel))
- Pos = ReadMethodPool(Sel, /*isInstance=*/false);
- else
- return 0;
- }
+ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
+ GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+ if (Pos == MethodPool.end())
+ return 0;
- ObjCMethodList &MethList = Pos->second;
- bool issueWarning = false;
+ GlobalMethods &Methods = Pos->second;
- if (MethList.Method && MethList.Next) {
- for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
- // This checks if the methods differ by size & alignment.
- if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
- issueWarning = true;
- }
- if (issueWarning && (MethList.Method && MethList.Next)) {
- Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
- Diag(MethList.Method->getLocStart(), diag::note_using)
- << MethList.Method->getSourceRange();
- for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
- Diag(Next->Method->getLocStart(), diag::note_also_found)
- << Next->Method->getSourceRange();
- }
- return MethList.Method;
+ if (Methods.first.Method && Methods.first.Method->isDefined())
+ return Methods.first.Method;
+ if (Methods.second.Method && Methods.second.Method->isDefined())
+ return Methods.second.Method;
+ return 0;
}
/// CompareMethodParamsInBaseAndSuper - This routine compares methods with
@@ -1322,12 +1290,10 @@ void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
// Note: For class/category implemenations, allMethods/allProperties is
// always null.
void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
- DeclPtrTy classDecl,
- DeclPtrTy *allMethods, unsigned allNum,
- DeclPtrTy *allProperties, unsigned pNum,
+ Decl *ClassDecl,
+ Decl **allMethods, unsigned allNum,
+ Decl **allProperties, unsigned pNum,
DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
- Decl *ClassDecl = classDecl.getAs<Decl>();
-
// FIXME: If we don't have a ClassDecl, we have an error. We should consider
// always passing in a decl. If the decl has an error, isInvalidDecl()
// should be true.
@@ -1356,7 +1322,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
for (unsigned i = 0; i < allNum; i++ ) {
ObjCMethodDecl *Method =
- cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
+ cast_or_null<ObjCMethodDecl>(allMethods[i]);
if (!Method) continue; // Already issued a diagnostic.
if (Method->isInstanceMethod()) {
@@ -1403,14 +1369,14 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
// Compares properties declared in this class to those of its
// super class.
ComparePropertiesInBaseAndSuper(I);
- CompareProperties(I, DeclPtrTy::make(I));
+ CompareProperties(I, I);
} else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
// Categories are used to extend the class by declaring new methods.
// By the same token, they are also used to add new properties. No
// need to compare the added property to those in the class.
// Compare protocol properties with those in category
- CompareProperties(C, DeclPtrTy::make(C));
+ CompareProperties(C, C);
if (C->IsClassExtension())
DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
}
@@ -1432,6 +1398,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
DefaultSynthesizeProperties(S, IC, IDecl);
ImplMethodsVsClassMethods(S, IC, IDecl);
AtomicPropertySetterGetterRules(IC, IDecl);
+
if (LangOpts.ObjCNonFragileABI2)
while (IDecl->getSuperClass()) {
DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
@@ -1491,19 +1458,20 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
}
static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
// The 'ibaction' attribute is allowed on method definitions because of
// how the IBAction macro is used on both method declarations and definitions.
// If the method definitions contains any other attributes, return true.
- while (A && A->getKind() == AttributeList::AT_IBAction)
- A = A->getNext();
- return A != NULL;
+ for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+ if ((*i)->getKind() != attr::IBAction)
+ return true;
+ return false;
}
-Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
+Decl *Sema::ActOnMethodDeclaration(
SourceLocation MethodLoc, SourceLocation EndLoc,
- tok::TokenKind MethodType, DeclPtrTy classDecl,
- ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+ tok::TokenKind MethodType, Decl *ClassDecl,
+ ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
@@ -1511,13 +1479,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
bool isVariadic) {
- Decl *ClassDecl = classDecl.getAs<Decl>();
-
// Make sure we can establish a context for the method.
if (!ClassDecl) {
Diag(MethodLoc, diag::error_missing_method_context);
- getLabelMap().clear();
- return DeclPtrTy();
+ getCurFunction()->LabelMap.clear();
+ return 0;
}
QualType resultDeclType;
@@ -1530,7 +1496,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
if (resultDeclType->isObjCObjectType()) {
Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
<< 0 << resultDeclType;
- return DeclPtrTy();
+ return 0;
}
} else // get the type for "id".
resultDeclType = Context.getObjCIdType();
@@ -1540,7 +1506,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
ResultTInfo,
cast<DeclContext>(ClassDecl),
MethodType == tok::minus, isVariadic,
- false,
+ false, false,
MethodDeclKind == tok::objc_optional ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
@@ -1563,7 +1529,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
ParmVarDecl* Param
= ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
ArgInfo[i].Name, ArgType, DI,
- VarDecl::None, VarDecl::None, 0);
+ SC_None, SC_None, 0);
if (ArgType->isObjCObjectType()) {
Diag(ArgInfo[i].NameLoc,
@@ -1582,7 +1548,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
}
for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
- ParmVarDecl *Param = CParamInfo[i].Param.getAs<ParmVarDecl>();
+ ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
QualType ArgType = Param->getType();
if (ArgType.isNull())
ArgType = Context.getObjCIdType();
@@ -1596,7 +1562,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
Param->setInvalidDecl();
}
Param->setDeclContext(ObjCMethod);
- IdResolver.RemoveDecl(Param);
+ if (Param->getDeclName())
+ IdResolver.RemoveDecl(Param);
Params.push_back(Param);
}
@@ -1626,7 +1593,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
}
InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
MethodType == tok::minus);
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
} else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1637,7 +1605,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
PrevMethod = CatImpDecl->getClassMethod(Sel);
CatImpDecl->addClassMethod(ObjCMethod);
}
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
}
if (PrevMethod) {
@@ -1649,14 +1618,16 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
// If the interface declared this method, and it was deprecated there,
// mark it deprecated here.
- if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
- ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+ if (InterfaceMD)
+ if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+ ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+ Context));
- return DeclPtrTy::make(ObjCMethod);
+ return ObjCMethod;
}
bool Sema::CheckObjCDeclScope(Decl *D) {
- if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
+ if (isa<TranslationUnitDecl>(CurContext->getRedeclContext()))
return false;
Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
@@ -1667,9 +1638,9 @@ bool Sema::CheckObjCDeclScope(Decl *D) {
/// Called whenever @defs(ClassName) is encountered in the source. Inserts the
/// instance variables of ClassName into Decls.
-void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
+ llvm::SmallVectorImpl<Decl*> &Decls) {
// Check that ClassName is a valid class
ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
if (!Class) {
@@ -1682,25 +1653,25 @@ void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
}
// Collect the instance variables
- llvm::SmallVector<FieldDecl*, 32> RecFields;
- Context.CollectObjCIvars(Class, RecFields);
+ llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+ Context.DeepCollectObjCIvars(Class, true, Ivars);
// For each ivar, create a fresh ObjCAtDefsFieldDecl.
- for (unsigned i = 0; i < RecFields.size(); i++) {
- FieldDecl* ID = RecFields[i];
- RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
+ for (unsigned i = 0; i < Ivars.size(); i++) {
+ FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
+ RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
ID->getIdentifier(), ID->getType(),
ID->getBitWidth());
- Decls.push_back(Sema::DeclPtrTy::make(FD));
+ Decls.push_back(FD);
}
// Introduce all of these fields into the appropriate scope.
- for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
+ for (llvm::SmallVectorImpl<Decl*>::iterator D = Decls.begin();
D != Decls.end(); ++D) {
- FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
+ FieldDecl *FD = cast<FieldDecl>(*D);
if (getLangOptions().CPlusPlus)
PushOnScopeChains(cast<FieldDecl>(FD), S);
- else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
+ else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
Record->addDecl(FD);
}
}
@@ -1735,7 +1706,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo,
}
VarDecl *New = VarDecl::Create(Context, CurContext, NameLoc, Name, T, TInfo,
- VarDecl::None, VarDecl::None);
+ SC_None, SC_None);
New->setExceptionVariable(true);
if (Invalid)
@@ -1743,7 +1714,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo,
return New;
}
-Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
const DeclSpec &DS = D.getDeclSpec();
// We allow the "register" storage class on exception variables because
@@ -1788,7 +1759,7 @@ Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
}
// Add the parameter declaration into this scope.
- S->AddDecl(DeclPtrTy::make(New));
+ S->AddDecl(New);
if (D.getIdentifier())
IdResolver.AddDecl(New);
@@ -1796,43 +1767,18 @@ Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
if (New->hasAttr<BlocksAttr>())
Diag(New->getLocation(), diag::err_block_on_nonlocal);
- return DeclPtrTy::make(New);
+ return New;
}
/// CollectIvarsToConstructOrDestruct - Collect those ivars which require
/// initialization.
-void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
+ for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv;
+ Iv= Iv->getNextIvar()) {
QualType QT = Context.getBaseElementType(Iv->getType());
if (QT->isRecordType())
- Ivars.push_back(*I);
- }
-
- // Find ivars to construct/destruct in class extension.
- for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
- CDecl = CDecl->getNextClassExtension()) {
- for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
- E = CDecl->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
- QualType QT = Context.getBaseElementType(Iv->getType());
- if (QT->isRecordType())
- Ivars.push_back(*I);
- }
- }
-
- // Also add any ivar defined in this class's implementation. This
- // includes synthesized ivars.
- if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
- for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
- E = ImplDecl->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *Iv = (*I);
- QualType QT = Context.getBaseElementType(Iv->getType());
- if (QT->isRecordType())
- Ivars.push_back(*I);
- }
+ Ivars.push_back(Iv);
}
}
@@ -1849,3 +1795,15 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
}
}
+void Sema::DiagnoseUseOfUnimplementedSelectors() {
+ if (ReferencedSelectors.empty())
+ return;
+ for (llvm::DenseMap<Selector, SourceLocation>::iterator S =
+ ReferencedSelectors.begin(),
+ E = ReferencedSelectors.end(); S != E; ++S) {
+ Selector Sel = (*S).first;
+ if (!LookupImplementedMethodInGlobalPool(Sel))
+ Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
+ }
+ return;
+}
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 34a479ae2a08..c902e7787096 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -261,6 +261,14 @@ bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
+ if (getLangOptions().Microsoft) {
+ // Treat throw(whatever) as throw(...) to be compatible with MS headers.
+ if (New->hasExceptionSpec() && New->getNumExceptions() > 0)
+ NewAny = true;
+ if (Old->hasExceptionSpec() && Old->getNumExceptions() > 0)
+ OldAny = true;
+ }
+
if (OldAny && NewAny)
return false;
if (OldAny || NewAny) {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5f46a977b12c..80b465230e14 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
@@ -29,11 +29,14 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Designator.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Template.h"
using namespace clang;
+using namespace sema;
/// \brief Determine whether the use of this declaration is valid, and
@@ -59,7 +62,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is unavailable
if (D->getAttr<UnavailableAttr>()) {
- Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+ Diag(Loc, diag::err_unavailable) << D->getDeclName();
Diag(D->getLocation(), diag::note_unavailable_here) << 0;
}
@@ -192,7 +195,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
if (Ty->isFunctionType())
ImpCastExprToType(E, Context.getPointerType(Ty),
- CastExpr::CK_FunctionToPointerDecay);
+ CK_FunctionToPointerDecay);
else if (Ty->isArrayType()) {
// In C90 mode, arrays only promote to pointers if the array expression is
// an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -208,7 +211,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
E->isLvalue(Context) == Expr::LV_Valid)
ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
}
}
@@ -229,7 +232,7 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
// If the lvalue has qualified type, the value has the unqualified
// version of the type of the lvalue; otherwise, the value has the
// type of the lvalue.
- ImpCastExprToType(E, Ty.getUnqualifiedType(), CastExpr::CK_NoOp);
+ ImpCastExprToType(E, Ty.getUnqualifiedType(), CK_NoOp);
}
}
@@ -258,12 +261,12 @@ Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
// other types are unchanged by the integer promotions.
QualType PTy = Context.isPromotableBitField(Expr);
if (!PTy.isNull()) {
- ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Expr, PTy, CK_IntegralCast);
return Expr;
}
if (Ty->isPromotableIntegerType()) {
QualType PT = Context.getPromotedIntegerType(Ty);
- ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Expr, PT, CK_IntegralCast);
return Expr;
}
@@ -281,7 +284,7 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
// If this is a 'float' (CVR qualified or typedef) promote to double.
if (Ty->isSpecificBuiltinType(BuiltinType::Float))
return ImpCastExprToType(Expr, Context.DoubleTy,
- CastExpr::CK_FloatingCast);
+ CK_FloatingCast);
UsualUnaryConversions(Expr);
}
@@ -355,8 +358,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs);
if (!isCompAssign)
- ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown);
- ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown);
+ ImpCastExprToType(lhsExpr, destType, CK_Unknown);
+ ImpCastExprToType(rhsExpr, destType, CK_Unknown);
return destType;
}
@@ -371,7 +374,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
/// multiple tokens. However, the common case is that StringToks points to one
/// string.
///
-Action::OwningExprResult
+ExprResult
Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
assert(NumStringToks && "Must have at least one string!");
@@ -459,13 +462,20 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock,
}
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+ const CXXScopeSpec *SS) {
+ DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
+ return BuildDeclRefExpr(D, Ty, NameInfo, SS);
+}
/// BuildDeclRefExpr - Build a DeclRefExpr.
-Sema::OwningExprResult
-Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+ const DeclarationNameInfo &NameInfo,
const CXXScopeSpec *SS) {
if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
- Diag(Loc,
+ Diag(NameInfo.getLoc(),
diag::err_auto_variable_cannot_appear_in_own_initializer)
<< D->getDeclName();
return ExprError();
@@ -479,7 +489,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
} else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
- Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function)
+ Diag(NameInfo.getLoc(),
+ diag::err_reference_to_local_var_in_enclosing_function)
<< D->getIdentifier() << FD->getDeclName();
Diag(D->getLocation(), diag::note_local_variable_declared_here)
<< D->getIdentifier();
@@ -489,12 +500,12 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
}
}
- MarkDeclarationReferenced(Loc, D);
+ MarkDeclarationReferenced(NameInfo.getLoc(), D);
return Owned(DeclRefExpr::Create(Context,
SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
SS? SS->getRange() : SourceRange(),
- D, Loc, Ty));
+ D, NameInfo, Ty));
}
/// \brief Given a field that represents a member of an anonymous
@@ -535,7 +546,7 @@ VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
return BaseObject;
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
FieldDecl *Field,
Expr *BaseObjectExpr,
@@ -553,7 +564,6 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
if (BaseObject) {
// BaseObject is an anonymous struct/union variable (and is,
// therefore, not part of another non-anonymous record).
- if (BaseObjectExpr) BaseObjectExpr->Destroy(Context);
MarkDeclarationReferenced(Loc, BaseObject);
BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(),
SourceLocation());
@@ -640,7 +650,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
return Owned(Result);
}
-/// Decomposes the given name into a DeclarationName, its location, and
+/// Decomposes the given name into a DeclarationNameInfo, its location, and
/// possibly a list of template arguments.
///
/// If this produces template arguments, it is permitted to call
@@ -652,8 +662,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
static void DecomposeUnqualifiedId(Sema &SemaRef,
const UnqualifiedId &Id,
TemplateArgumentListInfo &Buffer,
- DeclarationName &Name,
- SourceLocation &NameLoc,
+ DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *&TemplateArgs) {
if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
@@ -665,15 +674,12 @@ static void DecomposeUnqualifiedId(Sema &SemaRef,
SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer);
TemplateArgsPtr.release();
- TemplateName TName =
- Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
-
- Name = SemaRef.Context.getNameForTemplate(TName);
- NameLoc = Id.TemplateId->TemplateNameLoc;
+ TemplateName TName = Id.TemplateId->Template.get();
+ SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
+ NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
TemplateArgs = &Buffer;
} else {
- Name = SemaRef.GetNameFromUnqualifiedId(Id);
- NameLoc = Id.StartLocation;
+ NameInfo = SemaRef.GetNameFromUnqualifiedId(Id);
TemplateArgs = 0;
}
}
@@ -700,23 +706,6 @@ static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) {
return true;
}
-/// Determines whether we can lookup this id-expression now or whether
-/// we have to wait until template instantiation is complete.
-static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) {
- DeclContext *DC = SemaRef.computeDeclContext(SS, false);
-
- // If the qualifier scope isn't computable, it's definitely dependent.
- if (!DC) return true;
-
- // If the qualifier scope doesn't name a record, we can always look into it.
- if (!isa<CXXRecordDecl>(DC)) return false;
-
- // We can't look into record types unless they're fully-formed.
- if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true;
-
- return false;
-}
-
/// Determines if the given class is provably not derived from all of
/// the prospective base classes.
static bool IsProvablyNotDerivedFrom(Sema &SemaRef,
@@ -905,25 +894,30 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// TODO: fixit for inserting 'Base<T>::' in the other cases.
// Actually quite difficult!
if (isInstance) {
- Diag(R.getNameLoc(), diagnostic) << Name
- << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
-
UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
CallsUndergoingInstantiation.back()->getCallee());
- CXXMethodDecl *DepMethod = cast<CXXMethodDecl>(
+ CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
- QualType DepThisType = DepMethod->getThisType(Context);
- CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(),
- DepThisType, false);
- TemplateArgumentListInfo TList;
- if (ULE->hasExplicitTemplateArgs())
- ULE->copyTemplateArgumentsInto(TList);
- CXXDependentScopeMemberExpr *DepExpr =
- CXXDependentScopeMemberExpr::Create(
- Context, DepThis, DepThisType, true, SourceLocation(),
- ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name,
- R.getNameLoc(), &TList);
- CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+ if (DepMethod) {
+ Diag(R.getNameLoc(), diagnostic) << Name
+ << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+ QualType DepThisType = DepMethod->getThisType(Context);
+ CXXThisExpr *DepThis = new (Context) CXXThisExpr(
+ R.getNameLoc(), DepThisType, false);
+ TemplateArgumentListInfo TList;
+ if (ULE->hasExplicitTemplateArgs())
+ ULE->copyTemplateArgumentsInto(TList);
+ CXXDependentScopeMemberExpr *DepExpr =
+ CXXDependentScopeMemberExpr::Create(
+ Context, DepThis, DepThisType, true, SourceLocation(),
+ ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+ R.getLookupNameInfo(), &TList);
+ CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+ } else {
+ // FIXME: we should be able to handle this case too. It is correct
+ // to add this-> here. This is a workaround for PR7947.
+ Diag(R.getNameLoc(), diagnostic) << Name;
+ }
} else {
Diag(R.getNameLoc(), diagnostic) << Name;
}
@@ -935,6 +929,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// Tell the callee to try to recover.
return false;
}
+
+ R.clear();
}
}
@@ -1005,11 +1001,74 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
return true;
}
-Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
- CXXScopeSpec &SS,
- UnqualifiedId &Id,
- bool HasTrailingLParen,
- bool isAddressOfOperand) {
+static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ if (!ClassImpDecl)
+ return 0;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ return 0;
+ return property;
+}
+
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+ LookupResult &Lookup,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ bool LookForIvars;
+ if (Lookup.empty())
+ LookForIvars = true;
+ else if (CurMeth->isClassMethod())
+ LookForIvars = false;
+ else
+ LookForIvars = (Lookup.isSingleResult() &&
+ Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+ if (!LookForIvars)
+ return 0;
+
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ if (!ClassImpDecl)
+ return 0;
+ bool DynamicImplSeen = false;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ DynamicImplSeen =
+ (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+ if (!DynamicImplSeen) {
+ QualType PropType = SemaRef.Context.getCanonicalType(property->getType());
+ ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(SemaRef.Context, ClassImpDecl,
+ NameLoc,
+ II, PropType, /*Dinfo=*/0,
+ ObjCIvarDecl::Protected,
+ (Expr *)0, true);
+ ClassImpDecl->addDecl(Ivar);
+ IDecl->makeDeclVisibleInContext(Ivar, false);
+ property->setPropertyIvarDecl(Ivar);
+ return Ivar;
+ }
+ return 0;
+}
+
+ExprResult Sema::ActOnIdExpression(Scope *S,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Id,
+ bool HasTrailingLParen,
+ bool isAddressOfOperand) {
assert(!(isAddressOfOperand && HasTrailingLParen) &&
"cannot be direct & operand and have a trailing lparen");
@@ -1019,13 +1078,13 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
TemplateArgumentListInfo TemplateArgsBuffer;
// Decompose the UnqualifiedId into the following data.
- DeclarationName Name;
- SourceLocation NameLoc;
+ DeclarationNameInfo NameInfo;
const TemplateArgumentListInfo *TemplateArgs;
- DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
- Name, NameLoc, TemplateArgs);
+ DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
+ DeclarationName Name = NameInfo.getName();
IdentifierInfo *II = Name.getAsIdentifierInfo();
+ SourceLocation NameLoc = NameInfo.getLoc();
// C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
@@ -1038,16 +1097,30 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// names a dependent type.
// Determine whether this is a member of an unknown specialization;
// we need to handle these differently.
- if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
- Name.getCXXNameType()->isDependentType()) ||
- (SS.isSet() && IsDependentIdExpression(*this, SS))) {
- return ActOnDependentIdExpression(SS, Name, NameLoc,
- isAddressOfOperand,
- TemplateArgs);
+ bool DependentID = false;
+ if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+ Name.getCXXNameType()->isDependentType()) {
+ DependentID = true;
+ } else if (SS.isSet()) {
+ DeclContext *DC = computeDeclContext(SS, false);
+ if (DC) {
+ if (RequireCompleteDeclContext(SS, DC))
+ return ExprError();
+ // FIXME: We should be checking whether DC is the current instantiation.
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
+ DependentID = !IsFullyFormedScope(*this, RD);
+ } else {
+ DependentID = true;
+ }
}
+ if (DependentID) {
+ return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
+ TemplateArgs);
+ }
+ bool IvarLookupFollowUp = false;
// Perform the required lookup.
- LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
if (TemplateArgs) {
// Lookup the template name again to correctly establish the context in
// which it was found. This is really unfortunate as we already did the
@@ -1058,18 +1131,26 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false,
MemberOfUnknownSpecialization);
} else {
- bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+ IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
// If this reference is in an Objective-C method, then we need to do
// some special Objective-C lookup, too.
if (IvarLookupFollowUp) {
- OwningExprResult E(LookupInObjCMethod(R, S, II, true));
+ ExprResult E(LookupInObjCMethod(R, S, II, true));
if (E.isInvalid())
return ExprError();
Expr *Ex = E.takeAs<Expr>();
if (Ex) return Owned(Ex);
+ // Synthesize ivars lazily
+ if (getLangOptions().ObjCNonFragileABI2) {
+ if (SynthesizeProvisionalIvar(*this, R, II, NameLoc))
+ return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+ isAddressOfOperand);
+ }
+ // for further use, this must be set to false if in class method.
+ IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod();
}
}
@@ -1102,7 +1183,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// reference the ivar.
if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
R.clear();
- OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+ ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
assert(E.isInvalid() || E.get());
return move(E);
}
@@ -1113,23 +1194,15 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
assert(!R.empty() || ADL);
if (VarDecl *Var = R.getAsSingle<VarDecl>()) {
- // Warn about constructs like:
- // if (void *X = foo()) { ... } else { X }.
- // In the else block, the pointer is always false.
- if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
- Scope *CheckS = S;
- while (CheckS && CheckS->getControlParent()) {
- if ((CheckS->getFlags() & Scope::ElseScope) &&
- CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
- ExprError(Diag(NameLoc, diag::warn_value_always_zero)
- << Var->getDeclName()
- << (Var->getType()->isPointerType() ? 2 :
- Var->getType()->isBooleanType() ? 1 : 0));
- break;
- }
-
- // Move to the parent of this scope.
- CheckS = CheckS->getParent();
+ if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp &&
+ !getLangOptions().ObjCNonFragileABI2 &&
+ Var->isFileVarDecl()) {
+ ObjCPropertyDecl *Property =
+ OkToSynthesizeProvisionalIvar(*this, II, NameLoc);
+ if (Property) {
+ Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ Diag(Var->getLocation(), diag::note_global_declared_at);
}
}
} else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) {
@@ -1152,15 +1225,43 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
}
// Check whether this might be a C++ implicit instance member access.
- // C++ [expr.prim.general]p6:
- // Within the definition of a non-static member function, an
- // identifier that names a non-static member is transformed to a
- // class member access expression.
- // But note that &SomeClass::foo is grammatically distinct, even
- // though we don't parse it that way.
+ // C++ [class.mfct.non-static]p3:
+ // When an id-expression that is not part of a class member access
+ // syntax and not used to form a pointer to member is used in the
+ // body of a non-static member function of class X, if name lookup
+ // resolves the name in the id-expression to a non-static non-type
+ // member of some class C, the id-expression is transformed into a
+ // class member access expression using (*this) as the
+ // postfix-expression to the left of the . operator.
+ //
+ // But we don't actually need to do this for '&' operands if R
+ // resolved to a function or overloaded function set, because the
+ // expression is ill-formed if it actually works out to be a
+ // non-static member function:
+ //
+ // C++ [expr.ref]p4:
+ // Otherwise, if E1.E2 refers to a non-static member function. . .
+ // [t]he expression can be used only as the left-hand operand of a
+ // member function call.
+ //
+ // There are other safeguards against such uses, but it's important
+ // to get this right here so that we don't end up making a
+ // spuriously dependent expression if we're inside a dependent
+ // instance method.
if (!R.empty() && (*R.begin())->isCXXClassMember()) {
- bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty());
- if (!isAbstractMemberPointer)
+ bool MightBeImplicitMember;
+ if (!isAddressOfOperand)
+ MightBeImplicitMember = true;
+ else if (!SS.isEmpty())
+ MightBeImplicitMember = false;
+ else if (R.isOverloadedResult())
+ MightBeImplicitMember = false;
+ else if (R.isUnresolvableResult())
+ MightBeImplicitMember = true;
+ else
+ MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl());
+
+ if (MightBeImplicitMember)
return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs);
}
@@ -1171,7 +1272,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
}
/// Builds an expression which might be an implicit member expression.
-Sema::OwningExprResult
+ExprResult
Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs) {
@@ -1210,25 +1311,25 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
/// declaration name, generally during template instantiation.
/// There's a large number of things which don't need to be done along
/// this path.
-Sema::OwningExprResult
+ExprResult
Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc) {
+ const DeclarationNameInfo &NameInfo) {
DeclContext *DC;
if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
- return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+ return BuildDependentDeclRefExpr(SS, NameInfo, 0);
if (RequireCompleteDeclContext(SS, DC))
return ExprError();
- LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
LookupQualifiedName(R, DC);
if (R.isAmbiguous())
return ExprError();
if (R.empty()) {
- Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+ Diag(NameInfo.getLoc(), diag::err_no_member)
+ << NameInfo.getName() << DC << SS.getRange();
return ExprError();
}
@@ -1243,7 +1344,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
/// actually quite a lot of extra work involved.
///
/// Returns a null sentinel to indicate trivial success.
-Sema::OwningExprResult
+ExprResult
Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
IdentifierInfo *II, bool AllowBuiltinCreation) {
SourceLocation Loc = Lookup.getNameLoc();
@@ -1298,7 +1399,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
UnqualifiedId SelfName;
SelfName.setIdentifier(&II, SourceLocation());
CXXScopeSpec SelfScopeSpec;
- OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+ ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
SelfName, false, false);
MarkDeclarationReferenced(Loc, IV);
return Owned(new (Context)
@@ -1403,9 +1504,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
SourceRange FromRange = From->getSourceRange();
SourceLocation FromLoc = FromRange.getBegin();
- bool isLvalue
- = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions;
-
+ ExprValueKind VK = CastCategory(From);
+
// C++ [class.member.lookup]p8:
// [...] Ambiguities can often be resolved by qualifying a name with its
// class name.
@@ -1435,15 +1535,15 @@ Sema::PerformObjectMemberConversion(Expr *&From,
// type of the object type, in which case we just ignore it.
// Otherwise build the appropriate casts.
if (IsDerivedFrom(FromRecordType, QRecordType)) {
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
FromLoc, FromRange, &BasePath))
return true;
if (PointerConversions)
QType = Context.getPointerType(QType);
- ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
FromType = QType;
FromRecordType = QRecordType;
@@ -1471,7 +1571,7 @@ Sema::PerformObjectMemberConversion(Expr *&From,
// conversion is non-trivial.
if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
assert(IsDerivedFrom(FromRecordType, URecordType));
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, URecordType,
FromLoc, FromRange, &BasePath))
return true;
@@ -1479,8 +1579,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
QualType UType = URecordType;
if (PointerConversions)
UType = Context.getPointerType(UType);
- ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
FromType = UType;
FromRecordType = URecordType;
}
@@ -1490,14 +1590,14 @@ Sema::PerformObjectMemberConversion(Expr *&From,
IgnoreAccess = true;
}
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
FromLoc, FromRange, &BasePath,
IgnoreAccess))
return true;
- ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
return false;
}
@@ -1505,7 +1605,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
const CXXScopeSpec &SS, ValueDecl *Member,
DeclAccessPair FoundDecl,
- SourceLocation Loc, QualType Ty,
+ const DeclarationNameInfo &MemberNameInfo,
+ QualType Ty,
const TemplateArgumentListInfo *TemplateArgs = 0) {
NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange;
@@ -1515,14 +1616,15 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
}
return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
- Member, FoundDecl, Loc, TemplateArgs, Ty);
+ Member, FoundDecl, MemberNameInfo,
+ TemplateArgs, Ty);
}
/// Builds an implicit member access expression. The current context
/// is known to be an instance method, and the given unqualified lookup
/// set is known to contain only instance members, at least one of which
/// is from an appropriate type.
-Sema::OwningExprResult
+ExprResult
Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs,
@@ -1551,7 +1653,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
}
- return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
+ return BuildMemberReferenceExpr(This, ThisType,
/*OpLoc*/ SourceLocation(),
/*IsArrow*/ true,
SS,
@@ -1638,14 +1740,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
return false;
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R,
bool NeedsADL) {
// If this is a single, fully-resolved result and we don't need ADL,
// just build an ordinary singleton decl ref.
if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())
- return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
+ return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
+ R.getFoundDecl());
// We only need to check the declaration if there's exactly one
// result, because in the overloaded case the results can only be
@@ -1664,8 +1767,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
UnresolvedLookupExpr *ULE
= UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
(NestedNameSpecifier*) SS.getScopeRep(),
- SS.getRange(),
- R.getLookupName(), R.getNameLoc(),
+ SS.getRange(), R.getLookupNameInfo(),
NeedsADL, R.isOverloadedResult(),
R.begin(), R.end());
@@ -1674,13 +1776,15 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
/// \brief Complete semantic analysis for a reference to the given declaration.
-Sema::OwningExprResult
+ExprResult
Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
- SourceLocation Loc, NamedDecl *D) {
+ const DeclarationNameInfo &NameInfo,
+ NamedDecl *D) {
assert(D && "Cannot refer to a NULL declaration");
assert(!isa<FunctionTemplateDecl>(D) &&
"Cannot refer unambiguously to a function template");
+ SourceLocation Loc = NameInfo.getLoc();
if (CheckDeclInExpr(*this, Loc, D))
return ExprError();
@@ -1755,13 +1859,13 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T,
SourceLocation());
- OwningExprResult Res = PerformCopyInitialization(
+ ExprResult Res = PerformCopyInitialization(
InitializedEntity::InitializeBlock(VD->getLocation(),
T, false),
SourceLocation(),
Owned(E));
if (!Res.isInvalid()) {
- Res = MaybeCreateCXXExprWithTemporaries(move(Res));
+ Res = MaybeCreateCXXExprWithTemporaries(Res.get());
Expr *Init = Res.takeAs<Expr>();
BDRE->setCopyConstructorExpr(Init);
}
@@ -1772,10 +1876,11 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
// If this reference is not in a block or if the referenced variable is
// within the block, create a normal DeclRefExpr.
- return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS);
+ return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+ NameInfo, &SS);
}
-Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) {
PredefinedExpr::IdentType IT;
@@ -1790,6 +1895,8 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
// string.
Decl *currentDecl = getCurFunctionOrMethodDecl();
+ if (!currentDecl && getCurBlock())
+ currentDecl = getCurBlock()->TheDecl;
if (!currentDecl) {
Diag(Loc, diag::ext_predef_outside_function);
currentDecl = Context.getTranslationUnitDecl();
@@ -1808,7 +1915,7 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
}
-Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
+ExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
llvm::SmallString<16> CharBuffer;
bool Invalid = false;
llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid);
@@ -1835,13 +1942,13 @@ Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
Ty, Tok.getLocation()));
}
-Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
+ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// Fast path for a single digit (which is quite common). A single digit
// cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) {
const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
unsigned IntSize = Context.Target.getIntWidth();
- return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
+ return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
Context.IntTy, Tok.getLocation()));
}
@@ -1899,7 +2006,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
}
bool isExact = (result == APFloat::opOK);
- Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+ Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) {
return ExprError();
@@ -1986,7 +2093,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
if (ResultVal.getBitWidth() != Width)
ResultVal.trunc(Width);
}
- Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+ Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
}
// If this is an imaginary literal, create the ImaginaryLiteral wrapper.
@@ -1997,9 +2104,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
return Owned(Res);
}
-Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
- SourceLocation R, ExprArg Val) {
- Expr *E = Val.takeAs<Expr>();
+ExprResult Sema::ActOnParenExpr(SourceLocation L,
+ SourceLocation R, Expr *E) {
assert((E != 0) && "ActOnParenExpr() missing expr");
return Owned(new (Context) ParenExpr(L, R, E));
}
@@ -2083,7 +2189,7 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
}
/// \brief Build a sizeof or alignof expression given a type operand.
-Action::OwningExprResult
+ExprResult
Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
@@ -2104,7 +2210,7 @@ Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
/// \brief Build a sizeof or alignof expression given an expression
/// operand.
-Action::OwningExprResult
+ExprResult
Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
// Verify that the operand is valid.
@@ -2132,7 +2238,7 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
/// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and
/// the same for @c alignof and @c __alignof
/// Note that the ArgRange is invalid if isType is false.
-Action::OwningExprResult
+ExprResult
Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
void *TyOrEx, const SourceRange &ArgRange) {
// If error parsing type, ignore.
@@ -2140,17 +2246,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
if (isType) {
TypeSourceInfo *TInfo;
- (void) GetTypeFromParser(TyOrEx, &TInfo);
+ (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
}
Expr *ArgEx = (Expr *)TyOrEx;
- Action::OwningExprResult Result
+ ExprResult Result
= CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
- if (Result.isInvalid())
- DeleteExpr(ArgEx);
-
return move(Result);
}
@@ -2174,32 +2277,31 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
-Action::OwningExprResult
+ExprResult
Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Kind, ExprArg Input) {
- UnaryOperator::Opcode Opc;
+ tok::TokenKind Kind, Expr *Input) {
+ UnaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PostInc; break;
- case tok::minusminus: Opc = UnaryOperator::PostDec; break;
+ case tok::plusplus: Opc = UO_PostInc; break;
+ case tok::minusminus: Opc = UO_PostDec; break;
}
- return BuildUnaryOp(S, OpLoc, Opc, move(Input));
+ return BuildUnaryOp(S, OpLoc, Opc, Input);
}
-Action::OwningExprResult
-Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
- ExprArg Idx, SourceLocation RLoc) {
+ExprResult
+Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
+ Expr *Idx, SourceLocation RLoc) {
// Since this might be a postfix expression, get rid of ParenListExprs.
- Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.take();
- Expr *LHSExp = static_cast<Expr*>(Base.get()),
- *RHSExp = static_cast<Expr*>(Idx.get());
+ Expr *LHSExp = Base, *RHSExp = Idx;
if (getLangOptions().CPlusPlus &&
(LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
- Base.release();
- Idx.release();
return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
Context.DependentTy, RLoc));
}
@@ -2209,18 +2311,18 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
LHSExp->getType()->isEnumeralType() ||
RHSExp->getType()->isRecordType() ||
RHSExp->getType()->isEnumeralType())) {
- return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx));
+ return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx);
}
- return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc);
+ return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc);
}
-Action::OwningExprResult
-Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
- ExprArg Idx, SourceLocation RLoc) {
- Expr *LHSExp = static_cast<Expr*>(Base.get());
- Expr *RHSExp = static_cast<Expr*>(Idx.get());
+ExprResult
+Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+ Expr *Idx, SourceLocation RLoc) {
+ Expr *LHSExp = Base;
+ Expr *RHSExp = Idx;
// Perform default conversions.
if (!LHSExp->getType()->getAs<VectorType>())
@@ -2274,7 +2376,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
LHSExp->getSourceRange();
ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
LHSTy = LHSExp->getType();
BaseExpr = LHSExp;
@@ -2285,7 +2387,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
RHSExp->getSourceRange();
ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
RHSTy = RHSExp->getType();
BaseExpr = RHSExp;
@@ -2296,8 +2398,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
<< LHSExp->getSourceRange() << RHSExp->getSourceRange());
}
// C99 6.5.2.1p1
- if (!(IndexExpr->getType()->isIntegerType() &&
- IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+ if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
<< IndexExpr->getSourceRange());
@@ -2329,8 +2430,6 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
return ExprError();
}
- Base.release();
- Idx.release();
return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
ResultType, RLoc));
}
@@ -2377,7 +2476,7 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
// We didn't get to the end of the string. This means the component names
// didn't come from the same set *or* we encountered an illegal name.
Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
- << std::string(compStr,compStr+1) << SourceRange(CompLoc);
+ << llvm::StringRef(compStr, 1) << SourceRange(CompLoc);
return QualType();
}
@@ -2470,15 +2569,13 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
return GDecl;
}
-Sema::OwningExprResult
-Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
+ExprResult
+Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
bool IsArrow, SourceLocation OpLoc,
const CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- Expr *BaseExpr = Base.takeAs<Expr>();
-
// Even in dependent contexts, try to diagnose base expressions with
// obviously wrong types, e.g.:
//
@@ -2493,24 +2590,24 @@ Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
if (PT && (!getLangOptions().ObjC1 ||
PT->getPointeeType()->isRecordType())) {
assert(BaseExpr && "cannot happen with implicit member accesses");
- Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+ Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union)
<< BaseType << BaseExpr->getSourceRange();
return ExprError();
}
}
- assert(BaseType->isDependentType() || Name.isDependentName() ||
+ assert(BaseType->isDependentType() ||
+ NameInfo.getName().isDependentName() ||
isDependentScopeSpecifier(SS));
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
// must have pointer type, and the accessed type is the pointee.
return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
IsArrow, OpLoc,
- static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+ SS.getScopeRep(),
SS.getRange(),
FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs));
+ NameInfo, TemplateArgs));
}
/// We know that the given qualified member reference points only to
@@ -2562,12 +2659,15 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
return false;
// Note that we use the DC of the decl, not the underlying decl.
- CXXRecordDecl *RecordD = cast<CXXRecordDecl>((*I)->getDeclContext());
- while (RecordD->isAnonymousStructOrUnion())
- RecordD = cast<CXXRecordDecl>(RecordD->getParent());
+ DeclContext *DC = (*I)->getDeclContext();
+ while (DC->isTransparentContext())
+ DC = DC->getParent();
+ if (!DC->isRecord())
+ continue;
+
llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord;
- MemberRecord.insert(RecordD->getCanonicalDecl());
+ MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl());
if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord))
return false;
@@ -2646,24 +2746,21 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
return false;
}
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation OpLoc, bool IsArrow,
CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- Expr *Base = BaseArg.takeAs<Expr>();
-
if (BaseType->isDependentType() ||
(SS.isSet() && isDependentScopeSpecifier(SS)))
- return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
+ return ActOnDependentMemberExpr(Base, BaseType,
IsArrow, OpLoc,
SS, FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs);
+ NameInfo, TemplateArgs);
- LookupResult R(*this, Name, NameLoc, LookupMemberName);
+ LookupResult R(*this, NameInfo, LookupMemberName);
// Implicit member accesses.
if (!Base) {
@@ -2676,9 +2773,9 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
// Explicit member accesses.
} else {
- OwningExprResult Result =
+ ExprResult Result =
LookupMemberExpr(R, Base, IsArrow, OpLoc,
- SS, /*ObjCImpDecl*/ DeclPtrTy(), TemplateArgs != 0);
+ SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0);
if (Result.isInvalid()) {
Owned(Base);
@@ -2692,20 +2789,19 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
BaseType = Base->getType();
}
- return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
+ return BuildMemberReferenceExpr(Base, BaseType,
OpLoc, IsArrow, SS, FirstQualifierInScope,
R, TemplateArgs);
}
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
SourceLocation OpLoc, bool IsArrow,
const CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs,
bool SuppressQualifierCheck) {
- Expr *BaseExpr = Base.takeAs<Expr>();
QualType BaseType = BaseExprType;
if (IsArrow) {
assert(BaseType->isPointerType());
@@ -2713,10 +2809,10 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
}
R.setBaseObjectType(BaseType);
- NestedNameSpecifier *Qualifier =
- static_cast<NestedNameSpecifier*>(SS.getScopeRep());
- DeclarationName MemberName = R.getLookupName();
- SourceLocation MemberLoc = R.getNameLoc();
+ NestedNameSpecifier *Qualifier = SS.getScopeRep();
+ const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
+ DeclarationName MemberName = MemberNameInfo.getName();
+ SourceLocation MemberLoc = MemberNameInfo.getLoc();
if (R.isAmbiguous())
return ExprError();
@@ -2765,7 +2861,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
BaseExpr, BaseExprType,
IsArrow, OpLoc,
Qualifier, SS.getRange(),
- MemberName, MemberLoc,
+ MemberNameInfo,
TemplateArgs, R.begin(), R.end());
return Owned(MemExpr);
@@ -2787,7 +2883,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
if (!BaseExpr) {
// If this is not an instance member, convert to a non-member access.
if (!MemberDecl->isCXXInstanceMember())
- return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+ return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl);
SourceLocation Loc = R.getNameLoc();
if (SS.getRange().isValid())
@@ -2838,34 +2934,36 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
return ExprError();
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- FD, FoundDecl, MemberLoc, MemberType));
+ FD, FoundDecl, MemberNameInfo,
+ MemberType));
}
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, Var);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- Var, FoundDecl, MemberLoc,
+ Var, FoundDecl, MemberNameInfo,
Var->getType().getNonReferenceType()));
}
if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- MemberFn, FoundDecl, MemberLoc,
+ MemberFn, FoundDecl, MemberNameInfo,
MemberFn->getType()));
}
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- Enum, FoundDecl, MemberLoc, Enum->getType()));
+ Enum, FoundDecl, MemberNameInfo,
+ Enum->getType()));
}
Owned(BaseExpr);
// We found something that we didn't expect. Complain.
if (isa<TypeDecl>(MemberDecl))
- Diag(MemberLoc,diag::err_typecheck_member_reference_type)
+ Diag(MemberLoc, diag::err_typecheck_member_reference_type)
<< MemberName << BaseType << int(IsArrow);
else
Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
@@ -2887,11 +2985,11 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
///
/// The ObjCImpDecl bit is a gross hack that will need to be properly
/// fixed for ObjC++.
-Sema::OwningExprResult
+ExprResult
Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
- DeclPtrTy ObjCImpDecl, bool HasTemplateArgs) {
+ Decl *ObjCImpDecl, bool HasTemplateArgs) {
assert(BaseExpr && "no base expression");
// Perform default conversions.
@@ -2921,8 +3019,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
<< QualType(Fun, 0)
<< FixItHint::CreateInsertion(Loc, "()");
- OwningExprResult NewBase
- = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc,
+ ExprResult NewBase
+ = ActOnCallExpr(0, BaseExpr, Loc,
MultiExprArg(*this, 0, 0), 0, Loc);
BaseExpr = 0;
if (NewBase.isInvalid())
@@ -2952,7 +3050,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// is a reference to 'isa'.
if (BaseType != Context.ObjCIdRedefinitionType) {
BaseType = Context.ObjCIdRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
}
@@ -2963,7 +3061,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// is a reference to 'sel_id'.
if (BaseType != Context.ObjCSelRedefinitionType) {
BaseType = Context.ObjCSelRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
}
@@ -3022,7 +3120,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
if (BaseType->isObjCClassType() &&
BaseType != Context.ObjCClassRedefinitionType) {
BaseType = Context.ObjCClassRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
if (IsArrow) {
@@ -3129,12 +3227,11 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// down the context as argument to this routine. Ideally, this context
// need be passed down in the AST node and somehow calculated from the
// AST for a function decl.
- Decl *ImplDecl = ObjCImpDecl.getAs<Decl>();
if (ObjCImplementationDecl *IMPD =
- dyn_cast<ObjCImplementationDecl>(ImplDecl))
+ dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
ClassOfMethodDecl = IMPD->getClassInterface();
else if (ObjCCategoryImplDecl* CatImplClass =
- dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
+ dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
ClassOfMethodDecl = CatImplClass->getClassInterface();
}
@@ -3235,12 +3332,12 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
/// \param ObjCImpDecl the current ObjC @implementation decl;
/// this is an ugly hack around the fact that ObjC @implementations
/// aren't properly put in the context chain
-Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
+ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
CXXScopeSpec &SS,
UnqualifiedId &Id,
- DeclPtrTy ObjCImpDecl,
+ Decl *ObjCImpDecl,
bool HasTrailingLParen) {
if (SS.isSet() && SS.isInvalid())
return ExprError();
@@ -3248,12 +3345,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
TemplateArgumentListInfo TemplateArgsBuffer;
// Decompose the name into its component parts.
- DeclarationName Name;
- SourceLocation NameLoc;
+ DeclarationNameInfo NameInfo;
const TemplateArgumentListInfo *TemplateArgs;
DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
- Name, NameLoc, TemplateArgs);
+ NameInfo, TemplateArgs);
+ DeclarationName Name = NameInfo.getName();
bool IsArrow = (OpKind == tok::arrow);
NamedDecl *FirstQualifierInScope
@@ -3261,19 +3358,18 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
// This is a postfix expression, so get rid of ParenListExprs.
- BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.take();
- Expr *Base = BaseArg.takeAs<Expr>();
- OwningExprResult Result(*this);
if (Base->getType()->isDependentType() || Name.isDependentName() ||
isDependentScopeSpecifier(SS)) {
- Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
+ Result = ActOnDependentMemberExpr(Base, Base->getType(),
IsArrow, OpLoc,
SS, FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs);
+ NameInfo, TemplateArgs);
} else {
- LookupResult R(*this, Name, NameLoc, LookupMemberName);
+ LookupResult R(*this, NameInfo, LookupMemberName);
Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
SS, ObjCImpDecl, TemplateArgs != 0);
@@ -3289,12 +3385,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
// call now.
if (!HasTrailingLParen &&
Id.getKind() == UnqualifiedId::IK_DestructorName)
- return DiagnoseDtorReference(NameLoc, move(Result));
+ return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
return move(Result);
}
- Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
+ Result = BuildMemberReferenceExpr(Base, Base->getType(),
OpLoc, IsArrow, SS, FirstQualifierInScope,
R, TemplateArgs);
}
@@ -3302,7 +3398,7 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
return move(Result);
}
-Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
FunctionDecl *FD,
ParmVarDecl *Param) {
if (Param->hasUnparsedDefaultArg()) {
@@ -3324,7 +3420,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first,
Innermost.second);
- OwningExprResult Result = SubstExpr(UninstExpr, ArgList);
+ ExprResult Result = SubstExpr(UninstExpr, ArgList);
if (Result.isInvalid())
return ExprError();
@@ -3338,7 +3434,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&ResultE, 1));
+ MultiExprArg(*this, &ResultE, 1));
if (Result.isInvalid())
return ExprError();
@@ -3457,7 +3553,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
InitializedEntity Entity =
Param? InitializedEntity::InitializeParameter(Param)
: InitializedEntity::InitializeParameter(ProtoArgType);
- OwningExprResult ArgE = PerformCopyInitialization(Entity,
+ ExprResult ArgE = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(Arg));
if (ArgE.isInvalid())
@@ -3467,7 +3563,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
} else {
ParmVarDecl *Param = FDecl->getParamDecl(i);
- OwningExprResult ArgExpr =
+ ExprResult ArgExpr =
BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
if (ArgExpr.isInvalid())
return true;
@@ -3492,18 +3588,18 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
/// This provides the location of the left/right parens and a list of comma
/// locations.
-Action::OwningExprResult
-Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
+ExprResult
+Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
MultiExprArg args,
SourceLocation *CommaLocs, SourceLocation RParenLoc) {
unsigned NumArgs = args.size();
// Since this might be a postfix expression, get rid of ParenListExprs.
- fn = MaybeConvertParenListExprToParenExpr(S, move(fn));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
+ if (Result.isInvalid()) return ExprError();
+ Fn = Result.take();
- Expr *Fn = fn.takeAs<Expr>();
- Expr **Args = reinterpret_cast<Expr**>(args.release());
- assert(Fn && "no function call expression");
+ Expr **Args = args.release();
if (getLangOptions().CPlusPlus) {
// If this is a pseudo-destructor expression, build the call immediately.
@@ -3515,9 +3611,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
SourceRange(Args[0]->getLocStart(),
Args[NumArgs-1]->getLocEnd()));
- for (unsigned I = 0; I != NumArgs; ++I)
- Args[I]->Destroy(Context);
-
NumArgs = 0;
}
@@ -3572,27 +3665,27 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// Determine whether this is a call to a pointer-to-member function.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
- if (BO->getOpcode() == BinaryOperator::PtrMemD ||
- BO->getOpcode() == BinaryOperator::PtrMemI) {
+ if (BO->getOpcode() == BO_PtrMemD ||
+ BO->getOpcode() == BO_PtrMemI) {
if (const FunctionProtoType *FPT
= BO->getType()->getAs<FunctionProtoType>()) {
QualType ResultTy = FPT->getCallResultType(Context);
- ExprOwningPtr<CXXMemberCallExpr>
- TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
- NumArgs, ResultTy,
- RParenLoc));
+ CXXMemberCallExpr *TheCall
+ = new (Context) CXXMemberCallExpr(Context, BO, Args,
+ NumArgs, ResultTy,
+ RParenLoc);
if (CheckCallReturnType(FPT->getResultType(),
BO->getRHS()->getSourceRange().getBegin(),
- TheCall.get(), 0))
+ TheCall, 0))
return ExprError();
- if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
+ if (ConvertArgumentsForCall(TheCall, BO, 0, FPT, Args, NumArgs,
RParenLoc))
return ExprError();
- return Owned(MaybeBindToTemporary(TheCall.release()).release());
+ return MaybeBindToTemporary(TheCall);
}
return ExprError(Diag(Fn->getLocStart(),
diag::err_typecheck_call_not_function)
@@ -3625,7 +3718,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
/// block-pointer type.
///
/// \param NDecl the declaration being called, if available
-Sema::OwningExprResult
+ExprResult
Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
@@ -3637,10 +3730,10 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Make the call expr early, before semantic checks. This guarantees cleanup
// of arguments and function on error.
- ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn,
- Args, NumArgs,
- Context.BoolTy,
- RParenLoc));
+ CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
+ Args, NumArgs,
+ Context.BoolTy,
+ RParenLoc);
const FunctionType *FuncT;
if (!Fn->getType()->isBlockPointerType()) {
@@ -3661,7 +3754,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Check for a valid return type
if (CheckCallReturnType(FuncT->getResultType(),
- Fn->getSourceRange().getBegin(), TheCall.get(),
+ Fn->getSourceRange().getBegin(), TheCall,
FDecl))
return ExprError();
@@ -3669,7 +3762,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
TheCall->setType(FuncT->getCallResultType(Context));
if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
- if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
+ if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs,
RParenLoc))
return ExprError();
} else {
@@ -3713,22 +3806,22 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Do special checking on direct calls to functions.
if (FDecl) {
- if (CheckFunctionCall(FDecl, TheCall.get()))
+ if (CheckFunctionCall(FDecl, TheCall))
return ExprError();
if (unsigned BuiltinID = FDecl->getBuiltinID())
- return CheckBuiltinFunctionCall(BuiltinID, TheCall.take());
+ return CheckBuiltinFunctionCall(BuiltinID, TheCall);
} else if (NDecl) {
- if (CheckBlockCall(NDecl, TheCall.get()))
+ if (CheckBlockCall(NDecl, TheCall))
return ExprError();
}
- return MaybeBindToTemporary(TheCall.take());
+ return MaybeBindToTemporary(TheCall);
}
-Action::OwningExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprArg InitExpr) {
+ExprResult
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+ SourceLocation RParenLoc, Expr *InitExpr) {
assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
// FIXME: put back this assert when initializers are worked out.
//assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
@@ -3738,14 +3831,13 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(literalType);
- return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
}
-Action::OwningExprResult
+ExprResult
Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
- SourceLocation RParenLoc, ExprArg InitExpr) {
+ SourceLocation RParenLoc, Expr *literalExpr) {
QualType literalType = TInfo->getType();
- Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
if (literalType->isArrayType()) {
if (literalType->isVariableArrayType())
@@ -3764,13 +3856,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
= InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc),
/*IsCStyleCast=*/true);
InitializationSequence InitSeq(*this, Entity, Kind, &literalExpr, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&literalExpr, 1),
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &literalExpr, 1),
&literalType);
if (Result.isInvalid())
return ExprError();
- InitExpr.release();
- literalExpr = static_cast<Expr*>(Result.get());
+ literalExpr = Result.get();
bool isFileScope = getCurFunctionOrMethodDecl() == 0;
if (isFileScope) { // 6.5.2.5p3
@@ -3778,17 +3869,15 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
return ExprError();
}
- Result.release();
-
return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
literalExpr, isFileScope));
}
-Action::OwningExprResult
+ExprResult
Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
SourceLocation RBraceLoc) {
unsigned NumInit = initlist.size();
- Expr **InitList = reinterpret_cast<Expr**>(initlist.release());
+ Expr **InitList = initlist.release();
// Semantic analysis for initializers is done by ActOnDeclarator() and
// CheckInitializer() - it requires knowledge of the object being intialized.
@@ -3799,45 +3888,45 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
return Owned(E);
}
-static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+static CastKind getScalarCastKind(ASTContext &Context,
QualType SrcTy, QualType DestTy) {
if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
- return CastExpr::CK_NoOp;
+ return CK_NoOp;
if (SrcTy->hasPointerRepresentation()) {
if (DestTy->hasPointerRepresentation())
return DestTy->isObjCObjectPointerType() ?
- CastExpr::CK_AnyPointerToObjCPointerCast :
- CastExpr::CK_BitCast;
+ CK_AnyPointerToObjCPointerCast :
+ CK_BitCast;
if (DestTy->isIntegerType())
- return CastExpr::CK_PointerToIntegral;
+ return CK_PointerToIntegral;
}
if (SrcTy->isIntegerType()) {
if (DestTy->isIntegerType())
- return CastExpr::CK_IntegralCast;
+ return CK_IntegralCast;
if (DestTy->hasPointerRepresentation())
- return CastExpr::CK_IntegralToPointer;
+ return CK_IntegralToPointer;
if (DestTy->isRealFloatingType())
- return CastExpr::CK_IntegralToFloating;
+ return CK_IntegralToFloating;
}
if (SrcTy->isRealFloatingType()) {
if (DestTy->isRealFloatingType())
- return CastExpr::CK_FloatingCast;
+ return CK_FloatingCast;
if (DestTy->isIntegerType())
- return CastExpr::CK_FloatingToIntegral;
+ return CK_FloatingToIntegral;
}
// FIXME: Assert here.
// assert(false && "Unhandled cast combination!");
- return CastExpr::CK_Unknown;
+ return CK_Unknown;
}
/// CheckCastTypes - Check type constraints for casting between types.
bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
- CastExpr::CastKind& Kind,
- CXXBaseSpecifierArray &BasePath,
+ CastKind& Kind,
+ CXXCastPath &BasePath,
bool FunctionalStyle) {
if (getLangOptions().CPlusPlus)
return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
@@ -3849,10 +3938,14 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
// type needs to be scalar.
if (castType->isVoidType()) {
// Cast to void allows any expr type.
- Kind = CastExpr::CK_ToVoid;
+ Kind = CK_ToVoid;
return false;
}
+ if (RequireCompleteType(TyR.getBegin(), castType,
+ diag::err_typecheck_cast_to_incomplete))
+ return true;
+
if (!castType->isScalarType() && !castType->isVectorType()) {
if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
(castType->isStructureType() || castType->isUnionType())) {
@@ -3860,7 +3953,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
// FIXME: Check that the cast destination type is complete.
Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
<< castType << castExpr->getSourceRange();
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
return false;
}
@@ -3880,7 +3973,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
if (Field == FieldEnd)
return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
<< castExpr->getType() << castExpr->getSourceRange();
- Kind = CastExpr::CK_ToUnion;
+ Kind = CK_ToUnion;
return false;
}
@@ -3922,11 +4015,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
}
Kind = getScalarCastKind(Context, castExpr->getType(), castType);
+
+ if (Kind == CK_Unknown || Kind == CK_BitCast)
+ CheckCastAlign(castExpr, castType, TyR);
+
return false;
}
bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
assert(VectorTy->isVectorType() && "Not a vector type!");
if (Ty->isVectorType() || Ty->isIntegerType()) {
@@ -3941,12 +4038,12 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
diag::err_invalid_conversion_between_vector_and_scalar)
<< VectorTy << Ty << R;
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return false;
}
bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
QualType SrcTy = CastExpr->getType();
@@ -3957,7 +4054,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
<< DestTy << SrcTy << R;
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return false;
}
@@ -3973,14 +4070,14 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
ImpCastExprToType(CastExpr, DestElemTy,
getScalarCastKind(Context, SrcTy, DestElemTy));
- Kind = CastExpr::CK_VectorSplat;
+ Kind = CK_VectorSplat;
return false;
}
-Action::OwningExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprArg Op) {
- assert((Ty != 0) && (Op.get() != 0) &&
+ExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
+ SourceLocation RParenLoc, Expr *castExpr) {
+ assert((Ty != 0) && (castExpr != 0) &&
"ActOnCastExpr(): missing type or expr");
TypeSourceInfo *castTInfo;
@@ -3989,55 +4086,52 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
castTInfo = Context.getTrivialTypeSourceInfo(castType);
// If the Expr being casted is a ParenListExpr, handle it specially.
- Expr *castExpr = (Expr *)Op.get();
if (isa<ParenListExpr>(castExpr))
- return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),
+ return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr,
castTInfo);
- return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
+ return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr);
}
-Action::OwningExprResult
+ExprResult
Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
- SourceLocation RParenLoc, ExprArg Op) {
- Expr *castExpr = static_cast<Expr*>(Op.get());
-
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ SourceLocation RParenLoc, Expr *castExpr) {
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
Kind, BasePath))
return ExprError();
- Op.release();
- return Owned(new (Context) CStyleCastExpr(
+ return Owned(CStyleCastExpr::Create(Context,
Ty->getType().getNonLValueExprType(Context),
- Kind, castExpr, BasePath, Ty,
- LParenLoc, RParenLoc));
+ Kind, castExpr, &BasePath, Ty,
+ LParenLoc, RParenLoc));
}
/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
/// of comma binary operators.
-Action::OwningExprResult
-Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) {
- Expr *expr = EA.takeAs<Expr>();
+ExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) {
ParenListExpr *E = dyn_cast<ParenListExpr>(expr);
if (!E)
return Owned(expr);
- OwningExprResult Result(*this, E->getExpr(0));
+ ExprResult Result(E->getExpr(0));
for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i)
- Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result),
- Owned(E->getExpr(i)));
+ Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(),
+ E->getExpr(i));
- return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result));
+ if (Result.isInvalid()) return ExprError();
+
+ return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
}
-Action::OwningExprResult
+ExprResult
Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
- SourceLocation RParenLoc, ExprArg Op,
+ SourceLocation RParenLoc, Expr *Op,
TypeSourceInfo *TInfo) {
- ParenListExpr *PE = (ParenListExpr *)Op.get();
+ ParenListExpr *PE = cast<ParenListExpr>(Op);
QualType Ty = TInfo->getType();
bool isAltiVecLiteral = false;
@@ -4065,24 +4159,24 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
// FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas.
- Op.release();
InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc,
&initExprs[0],
initExprs.size(), RParenLoc);
E->setType(Ty);
- return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, E);
} else {
// This is not an AltiVec-style cast, so turn the ParenListExpr into a
// sequence of BinOp comma operators.
- Op = MaybeConvertParenListExprToParenExpr(S, move(Op));
- return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op);
+ if (Result.isInvalid()) return ExprError();
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take());
}
}
-Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
+ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
SourceLocation R,
MultiExprArg Val,
- TypeTy *TypeOfCast) {
+ ParsedType TypeOfCast) {
unsigned nexprs = Val.size();
Expr **exprs = reinterpret_cast<Expr**>(Val.release());
assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
@@ -4148,8 +4242,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (!RHSTy->isVoidType())
Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void)
<< LHS->getSourceRange();
- ImpCastExprToType(LHS, Context.VoidTy, CastExpr::CK_ToVoid);
- ImpCastExprToType(RHS, Context.VoidTy, CastExpr::CK_ToVoid);
+ ImpCastExprToType(LHS, Context.VoidTy, CK_ToVoid);
+ ImpCastExprToType(RHS, Context.VoidTy, CK_ToVoid);
return Context.VoidTy;
}
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
@@ -4157,12 +4251,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) &&
RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
// promote the null to a pointer.
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown);
+ ImpCastExprToType(RHS, LHSTy, CK_Unknown);
return LHSTy;
}
if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) &&
LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown);
+ ImpCastExprToType(LHS, RHSTy, CK_Unknown);
return RHSTy;
}
@@ -4178,8 +4272,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
QualType destType = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
@@ -4203,13 +4297,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// reason, but this is what gcc does, and we do have to pick
// to get a consistent AST.
QualType incompatTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The block pointer types are compatible.
- ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
@@ -4226,9 +4320,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(LHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -4236,9 +4330,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(RHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
return destType;
}
@@ -4254,8 +4348,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// reason, but this is what gcc does, and we do have to pick
// to get a consistent AST.
QualType incompatTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The pointer types are compatible.
@@ -4265,8 +4359,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// type.
// FIXME: Need to calculate the composite type.
// FIXME: Need to add qualifiers
- ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
@@ -4274,13 +4368,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(LHS, RHSTy, CK_IntegralToPointer);
return RHSTy;
}
if (LHSTy->isPointerType() && RHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(RHS, LHSTy, CK_IntegralToPointer);
return LHSTy;
}
@@ -4302,34 +4396,34 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
// redefinition type if an attempt is made to access its fields.
if (LHSTy->isObjCClassType() &&
(RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (RHSTy->isObjCClassType() &&
(LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// And the same for struct objc_object* / id
if (LHSTy->isObjCIdType() &&
(RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (RHSTy->isObjCIdType() &&
(LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// And the same for struct objc_selector* / SEL
if (Context.isObjCSelType(LHSTy) &&
(RHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (Context.isObjCSelType(RHSTy) &&
(LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// Check constraints for Objective-C object pointers types.
@@ -4378,13 +4472,13 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
<< LHSTy << RHSTy
<< LHS->getSourceRange() << RHS->getSourceRange();
QualType incompatTy = Context.getObjCIdType();
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The object pointer types are compatible.
- ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, compositeType, CK_BitCast);
+ ImpCastExprToType(RHS, compositeType, CK_BitCast);
return compositeType;
}
// Check Objective-C object pointer types and 'void *'
@@ -4395,9 +4489,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(LHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -4407,9 +4501,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(RHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
return destType;
}
return QualType();
@@ -4417,30 +4511,27 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
-Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
+ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
- ExprArg Cond, ExprArg LHS,
- ExprArg RHS) {
- Expr *CondExpr = (Expr *) Cond.get();
- Expr *LHSExpr = (Expr *) LHS.get(), *RHSExpr = (Expr *) RHS.get();
-
+ Expr *CondExpr, Expr *LHSExpr,
+ Expr *RHSExpr) {
// If this is the gnu "x ?: y" extension, analyze the types as though the LHS
// was the condition.
bool isLHSNull = LHSExpr == 0;
- if (isLHSNull)
- LHSExpr = CondExpr;
+ Expr *SAVEExpr = 0;
+ if (isLHSNull) {
+ LHSExpr = SAVEExpr = CondExpr;
+ }
QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
RHSExpr, QuestionLoc);
if (result.isNull())
return ExprError();
- Cond.release();
- LHS.release();
- RHS.release();
return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc,
- isLHSNull ? 0 : LHSExpr,
- ColonLoc, RHSExpr, result));
+ LHSExpr, ColonLoc,
+ RHSExpr, SAVEExpr,
+ result));
}
// CheckPointerTypesForAssignment - This is a very tricky routine (despite
@@ -4506,12 +4597,12 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
// "unsigned char" on systems where "char" is unsigned.
if (lhptee->isCharType())
lhptee = Context.UnsignedCharTy;
- else if (lhptee->isSignedIntegerType())
+ else if (lhptee->hasSignedIntegerRepresentation())
lhptee = Context.getCorrespondingUnsignedType(lhptee);
if (rhptee->isCharType())
rhptee = Context.UnsignedCharTy;
- else if (rhptee->isSignedIntegerType())
+ else if (rhptee->hasSignedIntegerRepresentation())
rhptee = Context.getCorrespondingUnsignedType(rhptee);
if (lhptee == rhptee) {
@@ -4668,13 +4759,18 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
}
if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // If we are allowing lax vector conversions, and LHS and RHS are both
- // vectors, the total size only needs to be the same. This is a bitcast;
- // no bits are changed but the result type is different.
- if (getLangOptions().LaxVectorConversions &&
- lhsType->isVectorType() && rhsType->isVectorType()) {
- if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+ if (lhsType->isVectorType() && rhsType->isVectorType()) {
+ // If we are allowing lax vector conversions, and LHS and RHS are both
+ // vectors, the total size only needs to be the same. This is a bitcast;
+ // no bits are changed but the result type is different.
+ if (getLangOptions().LaxVectorConversions &&
+ (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)))
return IncompatibleVectors;
+
+ // Allow assignments of an AltiVec vector type to an equivalent GCC
+ // vector type and vice versa
+ if (Context.areCompatibleVectorTypes(lhsType, rhsType))
+ return Compatible;
}
return Incompatible;
}
@@ -4832,14 +4928,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
// 2) null pointer constant
if (FromType->isPointerType())
if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
- ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast);
+ ImpCastExprToType(rExpr, it->getType(), CK_BitCast);
InitField = *it;
break;
}
if (rExpr->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer);
InitField = *it;
break;
}
@@ -4883,14 +4979,14 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
lhsType->isBlockPointerType())
&& rExpr->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown);
+ ImpCastExprToType(rExpr, lhsType, CK_Unknown);
return Compatible;
}
// This check seems unnatural, however it is necessary to ensure the proper
// conversion of functions/arrays. If the conversion were done for all
// DeclExpr's (created by ActOnIdExpression), it would mess up the unary
- // expressions that surpress this implicit conversion (&, sizeof).
+ // expressions that suppress this implicit conversion (&, sizeof).
//
// Suppress this for references: C++ 8.5.3p5.
if (!lhsType->isReferenceType())
@@ -4907,7 +5003,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
// does not have reference type.
if (result != Incompatible && rExpr->getType() != lhsType)
ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
- CastExpr::CK_Unknown);
+ CK_Unknown);
return result;
}
@@ -4933,22 +5029,35 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
// Handle the case of a vector & extvector type of the same size and element
// type. It would be nice if we only had one vector type someday.
if (getLangOptions().LaxVectorConversions) {
- // FIXME: Should we warn here?
if (const VectorType *LV = lhsType->getAs<VectorType>()) {
- if (const VectorType *RV = rhsType->getAs<VectorType>())
+ if (const VectorType *RV = rhsType->getAs<VectorType>()) {
if (LV->getElementType() == RV->getElementType() &&
LV->getNumElements() == RV->getNumElements()) {
if (lhsType->isExtVectorType()) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lhsType, CK_BitCast);
return lhsType;
}
- ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, rhsType, CK_BitCast);
return rhsType;
+ } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
+ // If we are allowing lax vector conversions, and LHS and RHS are both
+ // vectors, the total size only needs to be the same. This is a
+ // bitcast; no bits are changed but the result type is different.
+ ImpCastExprToType(rex, lhsType, CK_BitCast);
+ return lhsType;
}
+ }
}
}
+ // Handle the case of equivalent AltiVec and GCC vector types
+ if (lhsType->isVectorType() && rhsType->isVectorType() &&
+ Context.areCompatibleVectorTypes(lhsType, rhsType)) {
+ ImpCastExprToType(lex, rhsType, CK_BitCast);
+ return rhsType;
+ }
+
// Canonicalize the ExtVector to the LHS, remember if we swapped so we can
// swap back (so that we don't reverse the inputs to a subtract, for instance.
bool swapped = false;
@@ -4963,7 +5072,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
QualType EltTy = LV->getElementType();
if (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) {
if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(rex, lhsType, CK_IntegralCast);
if (swapped) std::swap(rex, lex);
return lhsType;
}
@@ -4971,7 +5080,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
rhsType->isRealFloatingType()) {
if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast);
+ ImpCastExprToType(rex, lhsType, CK_FloatingCast);
if (swapped) std::swap(rex, lex);
return lhsType;
}
@@ -5008,7 +5117,8 @@ QualType Sema::CheckMultiplyDivideOperands(
QualType Sema::CheckRemainderOperands(
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
- if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+ if (lex->getType()->hasIntegerRepresentation() &&
+ rex->getType()->hasIntegerRepresentation())
return CheckVectorOperands(Loc, lex, rex);
return InvalidOperands(Loc, lex, rex);
}
@@ -5253,7 +5363,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
bool isCompAssign) {
// C99 6.5.7p2: Each of the operands shall have integer type.
- if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+ if (!lex->getType()->hasIntegerRepresentation() ||
+ !rex->getType()->hasIntegerRepresentation())
return InvalidOperands(Loc, lex, rex);
// Vector shifts promote their scalar inputs to vector type.
@@ -5269,7 +5380,7 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
LHSTy = Context.getPromotedIntegerType(LHSTy);
}
if (!isCompAssign)
- ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(lex, LHSTy, CK_IntegralCast);
UsualUnaryConversions(rex);
@@ -5305,7 +5416,7 @@ static bool IsWithinTemplateSpecialization(Decl *D) {
// C99 6.5.8, C++ [expr.rel]
QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
unsigned OpaqueOpc, bool isRelational) {
- BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)OpaqueOpc;
+ BinaryOperatorKind Opc = (BinaryOperatorKind) OpaqueOpc;
// Handle vector comparisons separately.
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
@@ -5334,19 +5445,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
!IsWithinTemplateSpecialization(DRL->getDecl())) {
DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always)
<< 0 // self-
- << (Opc == BinaryOperator::EQ
- || Opc == BinaryOperator::LE
- || Opc == BinaryOperator::GE));
+ << (Opc == BO_EQ
+ || Opc == BO_LE
+ || Opc == BO_GE));
} else if (lType->isArrayType() && rType->isArrayType() &&
!DRL->getDecl()->getType()->isReferenceType() &&
!DRR->getDecl()->getType()->isReferenceType()) {
// what is it always going to eval to?
char always_evals_to;
switch(Opc) {
- case BinaryOperator::EQ: // e.g. array1 == array2
+ case BO_EQ: // e.g. array1 == array2
always_evals_to = 0; // false
break;
- case BinaryOperator::NE: // e.g. array1 != array2
+ case BO_NE: // e.g. array1 != array2
always_evals_to = 1; // true
break;
default:
@@ -5386,12 +5497,12 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (literalString) {
std::string resultComparison;
switch (Opc) {
- case BinaryOperator::LT: resultComparison = ") < 0"; break;
- case BinaryOperator::GT: resultComparison = ") > 0"; break;
- case BinaryOperator::LE: resultComparison = ") <= 0"; break;
- case BinaryOperator::GE: resultComparison = ") >= 0"; break;
- case BinaryOperator::EQ: resultComparison = ") == 0"; break;
- case BinaryOperator::NE: resultComparison = ") != 0"; break;
+ case BO_LT: resultComparison = ") < 0"; break;
+ case BO_GT: resultComparison = ") > 0"; break;
+ case BO_LE: resultComparison = ") <= 0"; break;
+ case BO_GE: resultComparison = ") >= 0"; break;
+ case BO_EQ: resultComparison = ") == 0"; break;
+ case BO_NE: resultComparison = ") != 0"; break;
default: assert(false && "Invalid comparison operator");
}
@@ -5461,7 +5572,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (isSFINAEContext())
return QualType();
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
}
@@ -5487,8 +5598,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
- ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, T, CK_BitCast);
+ ImpCastExprToType(rex, T, CK_BitCast);
return ResultTy;
}
// C99 6.5.9p2 and C99 6.5.8p2
@@ -5513,7 +5624,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
if (LCanPointeeTy != RCanPointeeTy)
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
@@ -5523,13 +5634,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (RHSIsNull &&
(lType->isPointerType() ||
(!isRelational && lType->isMemberPointerType()))) {
- ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(rex, lType,
+ lType->isMemberPointerType()
+ ? CK_NullToMemberPointer
+ : CK_IntegralToPointer);
return ResultTy;
}
if (LHSIsNull &&
(rType->isPointerType() ||
(!isRelational && rType->isMemberPointerType()))) {
- ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(lex, rType,
+ rType->isMemberPointerType()
+ ? CK_NullToMemberPointer
+ : CK_IntegralToPointer);
return ResultTy;
}
@@ -5560,8 +5677,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
- ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, T, CK_BitCast);
+ ImpCastExprToType(rex, T, CK_BitCast);
return ResultTy;
}
@@ -5580,7 +5697,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
// Allow block pointers to be compared with null pointer constants.
@@ -5595,7 +5712,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
@@ -5613,14 +5730,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
if (!Context.areComparableObjCPointerTypes(lType, rType))
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
}
@@ -5648,21 +5765,21 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if (lType->isIntegerType())
- ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(lex, rType, CK_IntegralToPointer);
else
- ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rex, lType, CK_IntegralToPointer);
return ResultTy;
}
// Handle block pointers.
if (!isRelational && RHSIsNull
&& lType->isBlockPointerType() && rType->isIntegerType()) {
- ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rex, lType, CK_IntegralToPointer);
return ResultTy;
}
if (!isRelational && LHSIsNull
&& lType->isIntegerType() && rType->isBlockPointerType()) {
- ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(lex, rType, CK_IntegralToPointer);
return ResultTy;
}
return InvalidOperands(Loc, lex, rex);
@@ -5707,7 +5824,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
// Return the type for the comparison, which is the same as vector type for
// integer vectors, or an integer type of identical size and number of
// elements for floating point vectors.
- if (lType->isIntegerType())
+ if (lType->hasIntegerRepresentation())
return lType;
const VectorType *VTy = lType->getAs<VectorType>();
@@ -5724,8 +5841,13 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
inline QualType Sema::CheckBitwiseOperands(
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+ if (lex->getType()->hasIntegerRepresentation() &&
+ rex->getType()->hasIntegerRepresentation())
+ return CheckVectorOperands(Loc, lex, rex);
+
+ return InvalidOperands(Loc, lex, rex);
+ }
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
@@ -5741,18 +5863,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
// bitwise one. We do this when the LHS is a non-bool integer and the RHS
// is a constant.
if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() &&
- rex->getType()->isIntegerType() && rex->isEvaluatable(Context) &&
- // Don't warn if the RHS is a (constant folded) boolean expression like
- // "sizeof(int) == 4".
- !rex->isKnownToHaveBooleanValue() &&
+ rex->getType()->isIntegerType() && !rex->isValueDependent() &&
// Don't warn in macros.
- !Loc.isMacroID())
- Diag(Loc, diag::warn_logical_instead_of_bitwise)
- << rex->getSourceRange()
- << (Opc == BinaryOperator::LAnd ? "&&" : "||")
- << (Opc == BinaryOperator::LAnd ? "&" : "|");
-
-
+ !Loc.isMacroID()) {
+ // If the RHS can be constant folded, and if it constant folds to something
+ // that isn't 0 or 1 (which indicate a potential logical operation that
+ // happened to fold to true/false) then warn.
+ Expr::EvalResult Result;
+ if (rex->Evaluate(Result, Context) && !Result.HasSideEffects &&
+ Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
+ Diag(Loc, diag::warn_logical_instead_of_bitwise)
+ << rex->getSourceRange()
+ << (Opc == BO_LAnd ? "&&" : "||")
+ << (Opc == BO_LAnd ? "&" : "|");
+ }
+ }
if (!Context.getLangOptions().CPlusPlus) {
UsualUnaryConversions(lex);
@@ -5907,8 +6032,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
RHSCheck = ICE->getSubExpr();
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
- if ((UO->getOpcode() == UnaryOperator::Plus ||
- UO->getOpcode() == UnaryOperator::Minus) &&
+ if ((UO->getOpcode() == UO_Plus ||
+ UO->getOpcode() == UO_Minus) &&
Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
// Only if the two operators are exactly adjacent.
Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() &&
@@ -5917,7 +6042,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
UO->getSubExpr()->getLocStart().isFileID()) {
Diag(Loc, diag::warn_not_compound_assign)
- << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-")
+ << (UO->getOpcode() == UO_Plus ? "+" : "-")
<< SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
}
}
@@ -5938,7 +6063,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
// only handles the pattern "*null = whatever", which is a very syntactic
// check.
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts()))
- if (UO->getOpcode() == UnaryOperator::Deref &&
+ if (UO->getOpcode() == UO_Deref &&
UO->getSubExpr()->IgnoreParenCasts()->
isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) &&
!UO->getType().isVolatileQualified()) {
@@ -6083,9 +6208,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
UnaryOperator *UO = cast<UnaryOperator>(E);
switch(UO->getOpcode()) {
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- case UnaryOperator::Extension:
+ case UO_Real:
+ case UO_Imag:
+ case UO_Extension:
return getPrimaryDecl(UO->getSubExpr());
default:
return 0;
@@ -6109,17 +6234,19 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
/// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue.
/// In C++, the operand might be an overloaded function name, in which case
/// we allow the '&' but retain the overloaded-function type.
-QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
- // Make sure to ignore parentheses in subsequent checks
- op = op->IgnoreParens();
-
- if (op->isTypeDependent())
+QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) {
+ if (OrigOp->isTypeDependent())
return Context.DependentTy;
+ if (OrigOp->getType() == Context.OverloadTy)
+ return Context.OverloadTy;
+
+ // Make sure to ignore parentheses in subsequent checks
+ Expr *op = OrigOp->IgnoreParens();
if (getLangOptions().C99) {
// Implement C99-only parts of addressof rules.
if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
- if (uOp->getOpcode() == UnaryOperator::Deref)
+ if (uOp->getOpcode() == UO_Deref)
// Per C99 6.5.3.2, the address of a deref always returns a valid result
// (assuming the deref expression is valid).
return uOp->getSubExpr()->getType();
@@ -6130,32 +6257,41 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
NamedDecl *dcl = getPrimaryDecl(op);
Expr::isLvalueResult lval = op->isLvalue(Context);
- MemberExpr *ME = dyn_cast<MemberExpr>(op);
- if (lval == Expr::LV_MemberFunction && ME &&
- isa<CXXMethodDecl>(ME->getMemberDecl())) {
- ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl();
- // &f where f is a member of the current object, or &o.f, or &p->f
- // All these are not allowed, and we need to catch them before the dcl
- // branch of the if, below.
- Diag(OpLoc, diag::err_unqualified_pointer_member_function)
- << dcl;
- // FIXME: Improve this diagnostic and provide a fixit.
-
- // Now recover by acting as if the function had been accessed qualified.
- return Context.getMemberPointerType(op->getType(),
- Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext()))
- .getTypePtr());
- }
-
if (lval == Expr::LV_ClassTemporary) {
Diag(OpLoc, isSFINAEContext()? diag::err_typecheck_addrof_class_temporary
: diag::ext_typecheck_addrof_class_temporary)
<< op->getType() << op->getSourceRange();
if (isSFINAEContext())
return QualType();
- } else if (isa<ObjCSelectorExpr>(op))
+ } else if (isa<ObjCSelectorExpr>(op)) {
return Context.getPointerType(op->getType());
- else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+ } else if (lval == Expr::LV_MemberFunction) {
+ // If it's an instance method, make a member pointer.
+ // The expression must have exactly the form &A::foo.
+
+ // If the underlying expression isn't a decl ref, give up.
+ if (!isa<DeclRefExpr>(op)) {
+ Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
+ << OrigOp->getSourceRange();
+ return QualType();
+ }
+ DeclRefExpr *DRE = cast<DeclRefExpr>(op);
+ CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
+
+ // The id-expression was parenthesized.
+ if (OrigOp != DRE) {
+ Diag(OpLoc, diag::err_parens_pointer_member_function)
+ << OrigOp->getSourceRange();
+
+ // The method was named without a qualifier.
+ } else if (!DRE->getQualifier()) {
+ Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+ << op->getSourceRange();
+ }
+
+ return Context.getMemberPointerType(op->getType(),
+ Context.getTypeDeclType(MD->getParent()).getTypePtr());
+ } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
// C99 6.5.3.2p1
// The operand must be either an l-value or a function designator
if (!op->getType()->isFunctionType()) {
@@ -6183,13 +6319,14 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
// FIXME: Can LHS ever be null here?
if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
- } else if (isa<UnresolvedLookupExpr>(op)) {
- return Context.OverloadTy;
} else if (dcl) { // C99 6.5.3.2p1
// We have an lvalue with a decl. Make sure the decl is not declared
// with the register storage-class specifier.
if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
- if (vd->getStorageClass() == VarDecl::Register) {
+ // in C++ it is not error to take address of a register
+ // variable (c++03 7.1.1P3)
+ if (vd->getStorageClass() == SC_Register &&
+ !getLangOptions().CPlusPlus) {
Diag(OpLoc, diag::err_typecheck_address_of)
<< "register variable" << op->getSourceRange();
return QualType();
@@ -6214,13 +6351,6 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
}
}
- } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) {
- // Okay: we can take the address of a function.
- // As above.
- if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
- MD->isInstance())
- return Context.getMemberPointerType(op->getType(),
- Context.getTypeDeclType(MD->getParent()).getTypePtr());
} else if (!isa<FunctionDecl>(dcl))
assert(0 && "Unknown/unexpected decl type");
}
@@ -6233,6 +6363,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
}
// If the operand has type "type", the result has type "pointer to type".
+ if (op->getType()->isObjCObjectType())
+ return Context.getObjCObjectPointerType(op->getType());
return Context.getPointerType(op->getType());
}
@@ -6264,63 +6396,63 @@ QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
return Result;
}
-static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
+static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode(
tok::TokenKind Kind) {
- BinaryOperator::Opcode Opc;
+ BinaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown binop!");
- case tok::periodstar: Opc = BinaryOperator::PtrMemD; break;
- case tok::arrowstar: Opc = BinaryOperator::PtrMemI; break;
- case tok::star: Opc = BinaryOperator::Mul; break;
- case tok::slash: Opc = BinaryOperator::Div; break;
- case tok::percent: Opc = BinaryOperator::Rem; break;
- case tok::plus: Opc = BinaryOperator::Add; break;
- case tok::minus: Opc = BinaryOperator::Sub; break;
- case tok::lessless: Opc = BinaryOperator::Shl; break;
- case tok::greatergreater: Opc = BinaryOperator::Shr; break;
- case tok::lessequal: Opc = BinaryOperator::LE; break;
- case tok::less: Opc = BinaryOperator::LT; break;
- case tok::greaterequal: Opc = BinaryOperator::GE; break;
- case tok::greater: Opc = BinaryOperator::GT; break;
- case tok::exclaimequal: Opc = BinaryOperator::NE; break;
- case tok::equalequal: Opc = BinaryOperator::EQ; break;
- case tok::amp: Opc = BinaryOperator::And; break;
- case tok::caret: Opc = BinaryOperator::Xor; break;
- case tok::pipe: Opc = BinaryOperator::Or; break;
- case tok::ampamp: Opc = BinaryOperator::LAnd; break;
- case tok::pipepipe: Opc = BinaryOperator::LOr; break;
- case tok::equal: Opc = BinaryOperator::Assign; break;
- case tok::starequal: Opc = BinaryOperator::MulAssign; break;
- case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
- case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
- case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
- case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
- case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
- case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
- case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
- case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
- case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
- case tok::comma: Opc = BinaryOperator::Comma; break;
+ case tok::periodstar: Opc = BO_PtrMemD; break;
+ case tok::arrowstar: Opc = BO_PtrMemI; break;
+ case tok::star: Opc = BO_Mul; break;
+ case tok::slash: Opc = BO_Div; break;
+ case tok::percent: Opc = BO_Rem; break;
+ case tok::plus: Opc = BO_Add; break;
+ case tok::minus: Opc = BO_Sub; break;
+ case tok::lessless: Opc = BO_Shl; break;
+ case tok::greatergreater: Opc = BO_Shr; break;
+ case tok::lessequal: Opc = BO_LE; break;
+ case tok::less: Opc = BO_LT; break;
+ case tok::greaterequal: Opc = BO_GE; break;
+ case tok::greater: Opc = BO_GT; break;
+ case tok::exclaimequal: Opc = BO_NE; break;
+ case tok::equalequal: Opc = BO_EQ; break;
+ case tok::amp: Opc = BO_And; break;
+ case tok::caret: Opc = BO_Xor; break;
+ case tok::pipe: Opc = BO_Or; break;
+ case tok::ampamp: Opc = BO_LAnd; break;
+ case tok::pipepipe: Opc = BO_LOr; break;
+ case tok::equal: Opc = BO_Assign; break;
+ case tok::starequal: Opc = BO_MulAssign; break;
+ case tok::slashequal: Opc = BO_DivAssign; break;
+ case tok::percentequal: Opc = BO_RemAssign; break;
+ case tok::plusequal: Opc = BO_AddAssign; break;
+ case tok::minusequal: Opc = BO_SubAssign; break;
+ case tok::lesslessequal: Opc = BO_ShlAssign; break;
+ case tok::greatergreaterequal: Opc = BO_ShrAssign; break;
+ case tok::ampequal: Opc = BO_AndAssign; break;
+ case tok::caretequal: Opc = BO_XorAssign; break;
+ case tok::pipeequal: Opc = BO_OrAssign; break;
+ case tok::comma: Opc = BO_Comma; break;
}
return Opc;
}
-static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
+static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
tok::TokenKind Kind) {
- UnaryOperator::Opcode Opc;
+ UnaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PreInc; break;
- case tok::minusminus: Opc = UnaryOperator::PreDec; break;
- case tok::amp: Opc = UnaryOperator::AddrOf; break;
- case tok::star: Opc = UnaryOperator::Deref; break;
- case tok::plus: Opc = UnaryOperator::Plus; break;
- case tok::minus: Opc = UnaryOperator::Minus; break;
- case tok::tilde: Opc = UnaryOperator::Not; break;
- case tok::exclaim: Opc = UnaryOperator::LNot; break;
- case tok::kw___real: Opc = UnaryOperator::Real; break;
- case tok::kw___imag: Opc = UnaryOperator::Imag; break;
- case tok::kw___extension__: Opc = UnaryOperator::Extension; break;
+ case tok::plusplus: Opc = UO_PreInc; break;
+ case tok::minusminus: Opc = UO_PreDec; break;
+ case tok::amp: Opc = UO_AddrOf; break;
+ case tok::star: Opc = UO_Deref; break;
+ case tok::plus: Opc = UO_Plus; break;
+ case tok::minus: Opc = UO_Minus; break;
+ case tok::tilde: Opc = UO_Not; break;
+ case tok::exclaim: Opc = UO_LNot; break;
+ case tok::kw___real: Opc = UO_Real; break;
+ case tok::kw___imag: Opc = UO_Imag; break;
+ case tok::kw___extension__: Opc = UO_Extension; break;
}
return Opc;
}
@@ -6328,106 +6460,111 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
/// CreateBuiltinBinOp - Creates a new built-in binary operation with
/// operator @p Opc at location @c TokLoc. This routine only supports
/// built-in operations; ActOnBinOp handles overloaded operators.
-Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
- unsigned Op,
- Expr *lhs, Expr *rhs) {
+ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
+ unsigned Op,
+ Expr *lhs, Expr *rhs) {
QualType ResultTy; // Result type of the binary operator.
- BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+ BinaryOperatorKind Opc = (BinaryOperatorKind) Op;
// The following two variables are used for compound assignment operators
QualType CompLHSTy; // Type of LHS after promotions for computation
QualType CompResultTy; // Type of computation result
switch (Opc) {
- case BinaryOperator::Assign:
+ case BO_Assign:
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
break;
- case BinaryOperator::PtrMemD:
- case BinaryOperator::PtrMemI:
+ case BO_PtrMemD:
+ case BO_PtrMemI:
ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc,
- Opc == BinaryOperator::PtrMemI);
+ Opc == BO_PtrMemI);
break;
- case BinaryOperator::Mul:
- case BinaryOperator::Div:
+ case BO_Mul:
+ case BO_Div:
ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
- Opc == BinaryOperator::Div);
+ Opc == BO_Div);
break;
- case BinaryOperator::Rem:
+ case BO_Rem:
ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Add:
+ case BO_Add:
ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Sub:
+ case BO_Sub:
ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Shl:
- case BinaryOperator::Shr:
+ case BO_Shl:
+ case BO_Shr:
ResultTy = CheckShiftOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::LE:
- case BinaryOperator::LT:
- case BinaryOperator::GE:
- case BinaryOperator::GT:
+ case BO_LE:
+ case BO_LT:
+ case BO_GE:
+ case BO_GT:
ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true);
break;
- case BinaryOperator::EQ:
- case BinaryOperator::NE:
+ case BO_EQ:
+ case BO_NE:
ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false);
break;
- case BinaryOperator::And:
- case BinaryOperator::Xor:
- case BinaryOperator::Or:
+ case BO_And:
+ case BO_Xor:
+ case BO_Or:
ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::LAnd:
- case BinaryOperator::LOr:
+ case BO_LAnd:
+ case BO_LOr:
ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc, Opc);
break;
- case BinaryOperator::MulAssign:
- case BinaryOperator::DivAssign:
+ case BO_MulAssign:
+ case BO_DivAssign:
CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
- Opc == BinaryOperator::DivAssign);
+ Opc == BO_DivAssign);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::RemAssign:
+ case BO_RemAssign:
CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::AddAssign:
+ case BO_AddAssign:
CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::SubAssign:
+ case BO_SubAssign:
CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::ShlAssign:
- case BinaryOperator::ShrAssign:
+ case BO_ShlAssign:
+ case BO_ShrAssign:
CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::AndAssign:
- case BinaryOperator::XorAssign:
- case BinaryOperator::OrAssign:
+ case BO_AndAssign:
+ case BO_XorAssign:
+ case BO_OrAssign:
CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::Comma:
+ case BO_Comma:
ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
break;
}
if (ResultTy.isNull())
return ExprError();
+ if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
+ if (Opc >= BO_Assign && Opc <= BO_OrAssign)
+ Diag(OpLoc, diag::err_assignment_requires_nonfragile_object)
+ << ResultTy;
+ }
if (CompResultTy.isNull())
return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
else
@@ -6479,7 +6616,7 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc,
/// operators are mixed in a way that suggests that the programmer forgot that
/// comparison operators have higher precedence. The most typical example of
/// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1".
-static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
SourceLocation OpLoc,Expr *lhs,Expr *rhs){
typedef BinaryOperator BinOp;
BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1),
@@ -6526,19 +6663,17 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
/// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3".
/// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does.
-static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
SourceLocation OpLoc, Expr *lhs, Expr *rhs){
if (BinaryOperator::isBitwiseOp(Opc))
DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
}
// Binary Operators. 'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
- tok::TokenKind Kind,
- ExprArg LHS, ExprArg RHS) {
- BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind);
- Expr *lhs = LHS.takeAs<Expr>(), *rhs = RHS.takeAs<Expr>();
-
+ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
+ tok::TokenKind Kind,
+ Expr *lhs, Expr *rhs) {
+ BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
assert((lhs != 0) && "ActOnBinOp(): missing left expression");
assert((rhs != 0) && "ActOnBinOp(): missing right expression");
@@ -6548,9 +6683,9 @@ Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
}
-Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
- BinaryOperator::Opcode Opc,
- Expr *lhs, Expr *rhs) {
+ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+ BinaryOperatorKind Opc,
+ Expr *lhs, Expr *rhs) {
if (getLangOptions().CPlusPlus &&
(lhs->getType()->isOverloadableType() ||
rhs->getType()->isOverloadableType())) {
@@ -6573,38 +6708,32 @@ Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
}
-Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
+ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
unsigned OpcIn,
- ExprArg InputArg) {
- UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+ Expr *Input) {
+ UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);
- // FIXME: Input is modified below, but InputArg is not updated appropriately.
- Expr *Input = (Expr *)InputArg.get();
QualType resultType;
switch (Opc) {
- case UnaryOperator::OffsetOf:
- assert(false && "Invalid unary operator");
- break;
-
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- case UnaryOperator::PostInc:
- case UnaryOperator::PostDec:
+ case UO_PreInc:
+ case UO_PreDec:
+ case UO_PostInc:
+ case UO_PostDec:
resultType = CheckIncrementDecrementOperand(Input, OpLoc,
- Opc == UnaryOperator::PreInc ||
- Opc == UnaryOperator::PostInc,
- Opc == UnaryOperator::PreInc ||
- Opc == UnaryOperator::PreDec);
+ Opc == UO_PreInc ||
+ Opc == UO_PostInc,
+ Opc == UO_PreInc ||
+ Opc == UO_PreDec);
break;
- case UnaryOperator::AddrOf:
+ case UO_AddrOf:
resultType = CheckAddressOfOperand(Input, OpLoc);
break;
- case UnaryOperator::Deref:
+ case UO_Deref:
DefaultFunctionArrayLvalueConversion(Input);
resultType = CheckIndirectionOperand(Input, OpLoc);
break;
- case UnaryOperator::Plus:
- case UnaryOperator::Minus:
+ case UO_Plus:
+ case UO_Minus:
UsualUnaryConversions(Input);
resultType = Input->getType();
if (resultType->isDependentType())
@@ -6616,13 +6745,13 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
resultType->isEnumeralType())
break;
else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6
- Opc == UnaryOperator::Plus &&
+ Opc == UO_Plus &&
resultType->isPointerType())
break;
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
- case UnaryOperator::Not: // bitwise complement
+ case UO_Not: // bitwise complement
UsualUnaryConversions(Input);
resultType = Input->getType();
if (resultType->isDependentType())
@@ -6632,11 +6761,11 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
// C99 does not support '~' for complex conjugation.
Diag(OpLoc, diag::ext_integer_complement_complex)
<< resultType << Input->getSourceRange();
- else if (!resultType->isIntegerType())
+ else if (!resultType->hasIntegerRepresentation())
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
break;
- case UnaryOperator::LNot: // logical negation
+ case UO_LNot: // logical negation
// Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
DefaultFunctionArrayLvalueConversion(Input);
resultType = Input->getType();
@@ -6649,27 +6778,25 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
// In C++, it's bool. C++ 5.3.1p8
resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
break;
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- resultType = CheckRealImagOperand(Input, OpLoc, Opc == UnaryOperator::Real);
+ case UO_Real:
+ case UO_Imag:
+ resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real);
break;
- case UnaryOperator::Extension:
+ case UO_Extension:
resultType = Input->getType();
break;
}
if (resultType.isNull())
return ExprError();
- InputArg.release();
return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc));
}
-Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
- UnaryOperator::Opcode Opc,
- ExprArg input) {
- Expr *Input = (Expr*)input.get();
+ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+ UnaryOperatorKind Opc,
+ Expr *Input) {
if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() &&
- Opc != UnaryOperator::Extension) {
+ UnaryOperator::getOverloadedOperator(Opc) != OO_None) {
// Find all of the overloaded operators visible from this
// point. We perform both an operator-name lookup from the local
// scope and an argument-dependent lookup based on the types of
@@ -6680,24 +6807,24 @@ Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
Functions);
- return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
+ return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
}
- return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
+ return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
}
// Unary Operators. 'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, ExprArg input) {
- return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input));
+ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+ tok::TokenKind Op, Expr *Input) {
+ return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), Input);
}
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
+ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
SourceLocation LabLoc,
IdentifierInfo *LabelII) {
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+ LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
// If we haven't seen this label yet, create a forward reference. It
// will be validated and/or cleaned up in ActOnFinishFunctionBody.
@@ -6709,10 +6836,9 @@ Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
Context.getPointerType(Context.VoidTy)));
}
-Sema::OwningExprResult
-Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
+ExprResult
+Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
SourceLocation RPLoc) { // "({..})"
- Stmt *SubStmt = static_cast<Stmt*>(substmt.get());
assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
@@ -6742,11 +6868,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
// FIXME: Check that expression type is complete/non-abstract; statement
// expressions are not lvalues.
- substmt.release();
return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc));
}
-Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
TypeSourceInfo *TInfo,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
@@ -6865,22 +6990,27 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
return ExprError();
}
-
+
+ RecordDecl *Parent = MemberDecl->getParent();
+ bool AnonStructUnion = Parent->isAnonymousStructOrUnion();
+ if (AnonStructUnion) {
+ do {
+ Parent = cast<RecordDecl>(Parent->getParent());
+ } while (Parent->isAnonymousStructOrUnion());
+ }
+
// If the member was found in a base class, introduce OffsetOfNodes for
// the base class indirections.
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
- if (IsDerivedFrom(CurrentType,
- Context.getTypeDeclType(MemberDecl->getParent()),
- Paths)) {
+ if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) {
CXXBasePath &Path = Paths.front();
for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
B != BEnd; ++B)
Comps.push_back(OffsetOfNode(B->Base));
}
-
- if (cast<RecordDecl>(MemberDecl->getDeclContext())->
- isAnonymousStructOrUnion()) {
+
+ if (AnonStructUnion) {
llvm::SmallVector<FieldDecl*, 4> Path;
BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
unsigned n = Path.size();
@@ -6897,10 +7027,10 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
Exprs.data(), Exprs.size(), RParenLoc));
}
-Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
+ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
SourceLocation BuiltinLoc,
SourceLocation TypeLoc,
- TypeTy *argty,
+ ParsedType argty,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
SourceLocation RPLoc) {
@@ -6910,151 +7040,32 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
if (ArgTy.isNull())
return ExprError();
- if (getLangOptions().CPlusPlus) {
- if (!ArgTInfo)
- ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
-
- return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents,
- RPLoc);
- }
-
- // FIXME: The code below is marked for death, once we have proper CodeGen
- // support for non-constant OffsetOf expressions.
-
- bool Dependent = ArgTy->isDependentType();
-
- // We must have at least one component that refers to the type, and the first
- // one is known to be a field designator. Verify that the ArgTy represents
- // a struct/union/class.
- if (!Dependent && !ArgTy->isRecordType())
- return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy);
-
- // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable
- // with an incomplete type would be illegal.
-
- // Otherwise, create a null pointer as the base, and iteratively process
- // the offsetof designators.
- QualType ArgTyPtr = Context.getPointerType(ArgTy);
- Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
- Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref,
- ArgTy, SourceLocation());
-
- // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
- // GCC extension, diagnose them.
- // FIXME: This diagnostic isn't actually visible because the location is in
- // a system header!
- if (NumComponents != 1)
- Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
- << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
-
- if (!Dependent) {
- bool DidWarnAboutNonPOD = false;
-
- if (RequireCompleteType(TypeLoc, Res->getType(),
- diag::err_offsetof_incomplete_type))
- return ExprError();
-
- // FIXME: Dependent case loses a lot of information here. And probably
- // leaks like a sieve.
- for (unsigned i = 0; i != NumComponents; ++i) {
- const OffsetOfComponent &OC = CompPtr[i];
- if (OC.isBrackets) {
- // Offset of an array sub-field. TODO: Should we allow vector elements?
- const ArrayType *AT = Context.getAsArrayType(Res->getType());
- if (!AT) {
- Res->Destroy(Context);
- return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
- << Res->getType());
- }
-
- // FIXME: C++: Verify that operator[] isn't overloaded.
-
- // Promote the array so it looks more like a normal array subscript
- // expression.
- DefaultFunctionArrayLvalueConversion(Res);
-
- // C99 6.5.2.1p1
- Expr *Idx = static_cast<Expr*>(OC.U.E);
- // FIXME: Leaks Res
- if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
- return ExprError(Diag(Idx->getLocStart(),
- diag::err_typecheck_subscript_not_integer)
- << Idx->getSourceRange());
-
- Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
- OC.LocEnd);
- continue;
- }
-
- const RecordType *RC = Res->getType()->getAs<RecordType>();
- if (!RC) {
- Res->Destroy(Context);
- return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
- << Res->getType());
- }
-
- // Get the decl corresponding to this.
- RecordDecl *RD = RC->getDecl();
- if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
- if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
- DiagRuntimeBehavior(BuiltinLoc,
- PDiag(diag::warn_offsetof_non_pod_type)
- << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
- << Res->getType()))
- DidWarnAboutNonPOD = true;
- }
-
- LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
- LookupQualifiedName(R, RD);
-
- FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
- // FIXME: Leaks Res
- if (!MemberDecl)
- return ExprError(Diag(BuiltinLoc, diag::err_no_member)
- << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
-
- // C99 7.17p3:
- // (If the specified member is a bit-field, the behavior is undefined.)
- //
- // We diagnose this as an error.
- if (MemberDecl->getBitWidth()) {
- Diag(OC.LocEnd, diag::err_offsetof_bitfield)
- << MemberDecl->getDeclName()
- << SourceRange(BuiltinLoc, RPLoc);
- Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
- return ExprError();
- }
-
- // FIXME: C++: Verify that MemberDecl isn't a static field.
- // FIXME: Verify that MemberDecl isn't a bitfield.
- if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
- Res = BuildAnonymousStructUnionMemberReference(
- OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
- } else {
- PerformObjectMemberConversion(Res, /*Qualifier=*/0,
- *R.begin(), MemberDecl);
- // MemberDecl->getType() doesn't get the right qualifiers, but it
- // doesn't matter here.
- Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
- MemberDecl->getType().getNonReferenceType());
- }
- }
- }
-
- return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
- Context.getSizeType(), BuiltinLoc));
+ if (!ArgTInfo)
+ ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
+
+ return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents,
+ RPLoc);
}
-Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1,TypeTy *arg2,
+ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ ParsedType arg1,ParsedType arg2,
SourceLocation RPLoc) {
- // FIXME: Preserve type source info.
- QualType argT1 = GetTypeFromParser(arg1);
- QualType argT2 = GetTypeFromParser(arg2);
+ TypeSourceInfo *argTInfo1;
+ QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
+ TypeSourceInfo *argTInfo2;
+ QualType argT2 = GetTypeFromParser(arg2, &argTInfo2);
assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
+ return BuildTypesCompatibleExpr(BuiltinLoc, argTInfo1, argTInfo2, RPLoc);
+}
+
+ExprResult
+Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ TypeSourceInfo *argTInfo1,
+ TypeSourceInfo *argTInfo2,
+ SourceLocation RPLoc) {
if (getLangOptions().CPlusPlus) {
Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus)
<< SourceRange(BuiltinLoc, RPLoc);
@@ -7062,17 +7073,14 @@ Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
}
return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc,
- argT1, argT2, RPLoc));
+ argTInfo1, argTInfo2, RPLoc));
}
-Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprArg cond,
- ExprArg expr1, ExprArg expr2,
- SourceLocation RPLoc) {
- Expr *CondExpr = static_cast<Expr*>(cond.get());
- Expr *LHSExpr = static_cast<Expr*>(expr1.get());
- Expr *RHSExpr = static_cast<Expr*>(expr2.get());
+ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+ Expr *CondExpr,
+ Expr *LHSExpr, Expr *RHSExpr,
+ SourceLocation RPLoc) {
assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
QualType resType;
@@ -7095,7 +7103,6 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
: RHSExpr->isValueDependent();
}
- cond.release(); expr1.release(); expr2.release();
return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
resType, RPLoc,
resType->isDependentType(),
@@ -7232,8 +7239,8 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
/// ActOnBlockStmtExpr - This is called when the body of a block statement
/// literal was successfully completed. ^(int x){...}
-Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
- StmtArg body, Scope *CurScope) {
+ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+ Stmt *Body, Scope *CurScope) {
// If blocks are disabled, emit an error.
if (!LangOpts.Blocks)
Diag(CaretLoc, diag::err_blocks_disable);
@@ -7295,10 +7302,10 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BlockTy = Context.getBlockPointerType(BlockTy);
// If needed, diagnose invalid gotos and switches in the block.
- if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
- DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get()));
+ if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+ DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
- BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+ BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
bool Good = true;
// Check goto/label use.
@@ -7320,22 +7327,29 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
return ExprError();
}
+ BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
+ BSI->hasBlockDeclRefExprs);
+
// Issue any analysis-based warnings.
const sema::AnalysisBasedWarnings::Policy &WP =
AnalysisWarnings.getDefaultPolicy();
- AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy);
+ AnalysisWarnings.IssueWarnings(WP, Result);
- Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
- BSI->hasBlockDeclRefExprs);
PopFunctionOrBlockScope();
return Owned(Result);
}
-Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
- ExprArg expr, TypeTy *type,
+ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+ Expr *expr, ParsedType type,
SourceLocation RPLoc) {
- QualType T = GetTypeFromParser(type);
- Expr *E = static_cast<Expr*>(expr.get());
+ TypeSourceInfo *TInfo;
+ QualType T = GetTypeFromParser(type, &TInfo);
+ return BuildVAArgExpr(BuiltinLoc, expr, TInfo, RPLoc);
+}
+
+ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
+ Expr *E, TypeSourceInfo *TInfo,
+ SourceLocation RPLoc) {
Expr *OrigExpr = E;
InitBuiltinVaListType();
@@ -7367,13 +7381,11 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
// FIXME: Check that type is complete/non-abstract
// FIXME: Warn if a non-POD type is passed in.
- expr.release();
- return Owned(new (Context) VAArgExpr(BuiltinLoc, E,
- T.getNonLValueExprType(Context),
- RPLoc));
+ QualType T = TInfo->getType().getNonLValueExprType(Context);
+ return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
}
-Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
// The type of __null will be int or long, depending on the size of
// pointers on the target.
QualType Ty;
@@ -7647,8 +7659,10 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
unsigned TypeQuals;
if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
- if (!Constructor->isUsed(false))
- DefineImplicitDefaultConstructor(Loc, Constructor);
+ if (Constructor->getParent()->hasTrivialConstructor())
+ return;
+ if (!Constructor->isUsed(false))
+ DefineImplicitDefaultConstructor(Loc, Constructor);
} else if (Constructor->isImplicit() &&
Constructor->isCopyConstructor(TypeQuals)) {
if (!Constructor->isUsed(false))
@@ -7696,13 +7710,20 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
Loc));
else
- PendingImplicitInstantiations.push_back(std::make_pair(Function,
- Loc));
+ PendingInstantiations.push_back(std::make_pair(Function, Loc));
+ }
+ } else // Walk redefinitions, as some of them may be instantiable.
+ for (FunctionDecl::redecl_iterator i(Function->redecls_begin()),
+ e(Function->redecls_end()); i != e; ++i) {
+ if (!i->isUsed(false) && i->isImplicitlyInstantiable())
+ MarkDeclarationReferenced(Loc, *i);
}
- }
// FIXME: keep track of references to static functions
- Function->setUsed(true);
+
+ // Recursive functions should be marked when used from another function.
+ if (CurContext != Function)
+ Function->setUsed(true);
return;
}
@@ -7716,7 +7737,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (MSInfo->getPointOfInstantiation().isInvalid() &&
MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
MSInfo->setPointOfInstantiation(Loc);
- PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc));
+ PendingInstantiations.push_back(std::make_pair(Var, Loc));
}
}
@@ -7836,7 +7857,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
if (isa<BinaryOperator>(E)) {
BinaryOperator *Op = cast<BinaryOperator>(E);
- if (Op->getOpcode() != BinaryOperator::Assign)
+ if (Op->getOpcode() != BO_Assign)
return;
// Greylist some idioms by putting them into a warning subcategory.
@@ -7899,16 +7920,13 @@ bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) {
return false;
}
-Sema::OwningExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- ExprArg SubExpr) {
- Expr *Sub = SubExpr.takeAs<Expr>();
+ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+ Expr *Sub) {
if (!Sub)
return ExprError();
- if (CheckBooleanCondition(Sub, Loc)) {
- Sub->Destroy(Context);
+ if (CheckBooleanCondition(Sub, Loc))
return ExprError();
- }
return Owned(Sub);
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 090400fc4e23..5720d931b66b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -11,28 +11,31 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
#include "llvm/ADT/STLExtras.h"
using namespace clang;
-
-Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II,
- SourceLocation NameLoc,
- Scope *S, CXXScopeSpec &SS,
- TypeTy *ObjectTypePtr,
- bool EnteringContext) {
+using namespace sema;
+
+ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II,
+ SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec &SS,
+ ParsedType ObjectTypePtr,
+ bool EnteringContext) {
// Determine where to perform name lookup.
// FIXME: This area of the standard is very messy, and the current
@@ -149,7 +152,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
// FIXME: Should we be suppressing ambiguities here?
if (Found.isAmbiguous())
- return 0;
+ return ParsedType();
if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
QualType T = Context.getTypeDeclType(Type);
@@ -158,7 +161,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
Context.hasSameUnqualifiedType(T, SearchType)) {
// We found our type!
- return T.getAsOpaquePtr();
+ return ParsedType::make(T);
}
}
@@ -191,7 +194,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
= dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
Template->getCanonicalDecl())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
}
continue;
@@ -210,7 +213,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
// specialized.
if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
continue;
}
@@ -221,7 +224,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
= SpecName.getAsDependentTemplateName()) {
if (DepTemplate->isIdentifier() &&
DepTemplate->getIdentifier() == Template->getIdentifier())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
continue;
}
@@ -242,8 +245,10 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
Range = SourceRange(NameLoc);
}
- return CheckTypenameType(ETK_None, NNS, II, SourceLocation(),
- Range, NameLoc).getAsOpaquePtr();
+ QualType T = CheckTypenameType(ETK_None, NNS, II,
+ SourceLocation(),
+ Range, NameLoc);
+ return ParsedType::make(T);
}
if (ObjectTypePtr)
@@ -252,11 +257,11 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
else
Diag(NameLoc, diag::err_destructor_class_name);
- return 0;
+ return ParsedType();
}
/// \brief Build a C++ typeid expression with a type operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
@@ -279,12 +284,11 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
}
/// \brief Build a C++ typeid expression with an expression operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
- ExprArg Operand,
+ Expr *E,
SourceLocation RParenLoc) {
bool isUnevaluatedOperand = true;
- Expr *E = static_cast<Expr *>(Operand.get());
if (E && !E->isTypeDependent()) {
QualType T = E->getType();
if (const RecordType *RecordT = T->getAs<RecordType>()) {
@@ -296,10 +300,10 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
return ExprError();
// C++ [expr.typeid]p3:
- // When typeid is applied to an expression other than an lvalue of a
+ // When typeid is applied to an expression other than an glvalue of a
// polymorphic class type [...] [the] expression is an unevaluated
// operand. [...]
- if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) {
+ if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) {
isUnevaluatedOperand = false;
// We require a vtable to query the type at run time.
@@ -316,9 +320,7 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
if (!Context.hasSameType(T, UnqualT)) {
T = UnqualT;
- ImpCastExprToType(E, UnqualT, CastExpr::CK_NoOp, E->isLvalue(Context));
- Operand.release();
- Operand = Owned(E);
+ ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E));
}
}
@@ -329,12 +331,12 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
ExprEvalContexts.back().Context = Unevaluated;
return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
- Operand.takeAs<Expr>(),
+ E,
SourceRange(TypeidLoc, RParenLoc)));
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
// Find the std::type_info type.
@@ -343,7 +345,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
- LookupQualifiedName(R, StdNamespace);
+ LookupQualifiedName(R, getStdNamespace());
RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
if (!TypeInfoRecordDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@@ -353,7 +355,8 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = 0;
- QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+ QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
+ &TInfo);
if (T.isNull())
return ExprError();
@@ -364,11 +367,11 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
}
// The operand is an expression.
- return BuildCXXTypeId(TypeInfoType, OpLoc, Owned((Expr*)TyOrExpr), RParenLoc);
+ return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
"Unknown C++ Boolean value!");
@@ -377,15 +380,14 @@ Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
}
/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
}
/// ActOnCXXThrow - Parse throw expressions.
-Action::OwningExprResult
-Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {
- Expr *Ex = E.takeAs<Expr>();
+ExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, Expr *Ex) {
if (Ex && !Ex->isTypeDependent() && CheckCXXThrowOperand(OpLoc, Ex))
return ExprError();
return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc));
@@ -400,8 +402,8 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
// the type from "array of T" or "function returning T" to "pointer to T"
// or "pointer to function returning T", [...]
if (E->getType().hasQualifiers())
- ImpCastExprToType(E, E->getType().getUnqualifiedType(), CastExpr::CK_NoOp,
- E->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
+ CastCategory(E));
DefaultFunctionArrayConversion(E);
@@ -432,7 +434,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
InitializedEntity Entity =
InitializedEntity::InitializeException(ThrowLoc, E->getType(),
/*NRVO=*/false);
- OwningExprResult Res = PerformCopyInitialization(Entity,
+ ExprResult Res = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(E));
if (Res.isInvalid())
@@ -464,7 +466,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
return false;
}
-Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
/// C++ 9.3.2: In the body of a non-static member function, the keyword this
/// is a non-lvalue expression whose value is the address of the object for
/// which the function is called.
@@ -483,8 +485,8 @@ Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
/// Can be interpreted either as function-style casting ("int(x)")
/// or class type construction ("ClassType(x,y,z)")
/// or creation of a value-initialized type ("int()").
-Action::OwningExprResult
-Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+ExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep,
SourceLocation LParenLoc,
MultiExprArg exprs,
SourceLocation *CommaLocs,
@@ -532,19 +534,19 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
// corresponding cast expression.
//
if (NumExprs == 1) {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath,
/*FunctionalStyle=*/true))
return ExprError();
exprs.release();
- return Owned(new (Context) CXXFunctionalCastExpr(
+ return Owned(CXXFunctionalCastExpr::Create(Context,
Ty.getNonLValueExprType(Context),
- TInfo, TyBeginLoc, Kind,
- Exprs[0], BasePath,
- RParenLoc));
+ TInfo, TyBeginLoc, Kind,
+ Exprs[0], &BasePath,
+ RParenLoc));
}
if (Ty->isRecordType()) {
@@ -555,7 +557,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
: InitializationKind::CreateValue(TypeRange.getBegin(),
LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
move(exprs));
// FIXME: Improve AST representation?
@@ -587,7 +589,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
/// or
/// @code ::new Foo(23, "hello") @endcode
/// For the interpretation of this heap of arguments, consult the base version.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
@@ -643,13 +645,13 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
AllocType,
D.getSourceRange().getBegin(),
R,
- Owned(ArraySize),
+ ArraySize,
ConstructorLParen,
move(ConstructorArgs),
ConstructorRParen);
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
@@ -658,7 +660,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
QualType AllocType,
SourceLocation TypeLoc,
SourceRange TypeRange,
- ExprArg ArraySizeE,
+ Expr *ArraySize,
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
@@ -667,12 +669,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
- if (!ArraySizeE.get()) {
+ if (!ArraySize) {
if (const ConstantArrayType *Array
= Context.getAsConstantArrayType(AllocType)) {
- ArraySizeE = Owned(new (Context) IntegerLiteral(Array->getSize(),
- Context.getSizeType(),
- TypeRange.getEnd()));
+ ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
+ Context.getSizeType(),
+ TypeRange.getEnd());
AllocType = Array->getElementType();
}
}
@@ -681,13 +683,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
// C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
// or enumeration type with a non-negative value."
- Expr *ArraySize = (Expr *)ArraySizeE.get();
if (ArraySize && !ArraySize->isTypeDependent()) {
QualType SizeType = ArraySize->getType();
- OwningExprResult ConvertedSize
- = ConvertToIntegralOrEnumerationType(StartLoc, move(ArraySizeE),
+ ExprResult ConvertedSize
+ = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
PDiag(diag::err_array_size_not_integral),
PDiag(diag::err_array_size_incomplete_type)
<< ArraySize->getSourceRange(),
@@ -700,8 +701,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (ConvertedSize.isInvalid())
return ExprError();
- ArraySize = ConvertedSize.takeAs<Expr>();
- ArraySizeE = Owned(ArraySize);
+ ArraySize = ConvertedSize.take();
SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrEnumerationType())
return ExprError();
@@ -716,8 +716,20 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
llvm::APInt::getNullValue(Value.getBitWidth()),
Value.isUnsigned()))
return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
- diag::err_typecheck_negative_array_size)
+ diag::err_typecheck_negative_array_size)
<< ArraySize->getSourceRange());
+
+ if (!AllocType->isDependentType()) {
+ unsigned ActiveSizeBits
+ = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
+ if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+ Diag(ArraySize->getSourceRange().getBegin(),
+ diag::err_array_too_large)
+ << Value.toString(10)
+ << ArraySize->getSourceRange();
+ return ExprError();
+ }
+ }
} else if (TypeIdParens.isValid()) {
// Can't have dynamic array size when the type-id is in parentheses.
Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst)
@@ -730,7 +742,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
}
ImpCastExprToType(ArraySize, Context.getSizeType(),
- CastExpr::CK_IntegralCast);
+ CK_IntegralCast);
}
FunctionDecl *OperatorNew = 0;
@@ -768,7 +780,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
CXXConstructorDecl *Constructor = 0;
Expr **ConsArgs = (Expr**)ConstructorArgs.get();
unsigned NumConsArgs = ConstructorArgs.size();
- ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this);
+ ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
// Array 'new' can't have any initializers.
if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
@@ -798,7 +810,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);
InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
- OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
+ ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
move(ConstructorArgs));
if (FullInit.isInvalid())
return ExprError();
@@ -839,7 +851,6 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
PlacementArgs.release();
ConstructorArgs.release();
- ArraySizeE.release();
// FIXME: The TypeSourceInfo should also be included in CXXNewExpr.
return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
@@ -911,7 +922,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// We don't care about the actual value of this argument.
// FIXME: Should the Sema create the expression and embed it in the syntax
// tree? Or should the consumer just recalculate the value?
- IntegerLiteral Size(llvm::APInt::getNullValue(
+ IntegerLiteral Size(Context, llvm::APInt::getNullValue(
Context.Target.getPointerWidth(0)),
Context.getSizeType(),
SourceLocation());
@@ -929,9 +940,11 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
IsArray ? OO_Array_Delete : OO_Delete);
- if (AllocType->isRecordType() && !UseGlobal) {
+ QualType AllocElemType = Context.getBaseElementType(AllocType);
+
+ if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *Record
- = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+ = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
AllocArgs.size(), Record, /*AllowMissing=*/true,
OperatorNew))
@@ -969,9 +982,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// the allocated type is not a class type or array thereof, the
// deallocation function’s name is looked up in the global scope.
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
- if (AllocType->isRecordType() && !UseGlobal) {
+ if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *RD
- = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+ = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
LookupQualifiedName(FoundDelete, RD);
}
if (FoundDelete.isAmbiguous())
@@ -1115,7 +1128,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
// Do the resolution.
OverloadCandidateSet::iterator Best;
- switch(BestViableFunction(Candidates, StartLoc, Best)) {
+ switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
case OR_Success: {
// Got one!
FunctionDecl *FnDecl = Best->Function;
@@ -1125,7 +1138,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
// Watch out for variadic allocator function.
unsigned NumArgsInFnDecl = FnDecl->getNumParams();
for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
- OwningExprResult Result
+ ExprResult Result
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(i)),
SourceLocation(),
@@ -1143,20 +1156,20 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
case OR_No_Viable_Function:
Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
case OR_Ambiguous:
Diag(StartLoc, diag::err_ovl_ambiguous_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
return true;
case OR_Deleted:
Diag(StartLoc, diag::err_ovl_deleted_call)
<< Best->Function->isDeleted()
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
}
assert(false && "Unreachable, bad result from BestViableFunction");
@@ -1199,11 +1212,11 @@ void Sema::DeclareGlobalNewDelete() {
// The "std::bad_alloc" class has not yet been declared, so build it
// implicitly.
StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
- getStdNamespace(),
+ getOrCreateStdNamespace(),
SourceLocation(),
&PP.getIdentifierTable().get("bad_alloc"),
SourceLocation(), 0);
- StdBadAlloc->setImplicit(true);
+ getStdBadAlloc()->setImplicit(true);
}
GlobalNewDeleteDeclared = true;
@@ -1245,8 +1258,11 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
Context.getCanonicalType(
Func->getParamDecl(0)->getType().getUnqualifiedType());
// FIXME: Do we need to check for default arguments here?
- if (Func->getNumParams() == 1 && InitialParamType == Argument)
+ if (Func->getNumParams() == 1 && InitialParamType == Argument) {
+ if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
+ Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
return;
+ }
}
}
}
@@ -1257,7 +1273,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
Name.getCXXOverloadedOperator() == OO_Array_New);
if (HasBadAllocExceptionSpec) {
assert(StdBadAlloc && "Must have std::bad_alloc declared");
- BadAllocType = Context.getTypeDeclType(StdBadAlloc);
+ BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
}
QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
@@ -1267,23 +1283,23 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
FunctionType::ExtInfo());
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
- FnType, /*TInfo=*/0, FunctionDecl::None,
- FunctionDecl::None, false, true);
+ FnType, /*TInfo=*/0, SC_None,
+ SC_None, false, true);
Alloc->setImplicit();
if (AddMallocAttr)
- Alloc->addAttr(::new (Context) MallocAttr());
+ Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
- VarDecl::None,
- VarDecl::None, 0);
+ SC_None,
+ SC_None, 0);
Alloc->setParams(&Param, 1);
// FIXME: Also add this declaration to the IdentifierResolver, but
// make sure it is at the end of the chain to coincide with the
// global scope.
- ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
+ Context.getTranslationUnitDecl()->addDecl(Alloc);
}
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
@@ -1298,15 +1314,37 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
Found.suppressDiagnostics();
+ llvm::SmallVector<DeclAccessPair,4> Matches;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F) {
- if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
- if (Delete->isUsualDeallocationFunction()) {
- Operator = Delete;
- CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
- F.getPair());
- return false;
- }
+ NamedDecl *ND = (*F)->getUnderlyingDecl();
+
+ // Ignore template operator delete members from the check for a usual
+ // deallocation function.
+ if (isa<FunctionTemplateDecl>(ND))
+ continue;
+
+ if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction())
+ Matches.push_back(F.getPair());
+ }
+
+ // There's exactly one suitable operator; pick it.
+ if (Matches.size() == 1) {
+ Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
+ CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
+ Matches[0]);
+ return false;
+
+ // We found multiple suitable operators; complain about the ambiguity.
+ } else if (!Matches.empty()) {
+ Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
+ << Name << RD;
+
+ for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
+ F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
+ Diag((*F)->getUnderlyingDecl()->getLocation(),
+ diag::note_member_declared_here) << Name;
+ return true;
}
// We did find operator delete/operator delete[] declarations, but
@@ -1316,10 +1354,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
<< Name << RD;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
- F != FEnd; ++F) {
- Diag((*F)->getLocation(), diag::note_member_declared_here)
- << Name;
- }
+ F != FEnd; ++F)
+ Diag((*F)->getUnderlyingDecl()->getLocation(),
+ diag::note_member_declared_here) << Name;
return true;
}
@@ -1344,9 +1381,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
/// @code ::delete ptr; @endcode
/// or
/// @code delete [] ptr; @endcode
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
- bool ArrayForm, ExprArg Operand) {
+ bool ArrayForm, Expr *Ex) {
// C++ [expr.delete]p1:
// The operand shall have a pointer type, or a class type having a single
// conversion function to a pointer type. The result has type void.
@@ -1355,11 +1392,14 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
FunctionDecl *OperatorDelete = 0;
- Expr *Ex = (Expr *)Operand.get();
if (!Ex->isTypeDependent()) {
QualType Type = Ex->getType();
if (const RecordType *Record = Type->getAs<RecordType>()) {
+ if (RequireCompleteType(StartLoc, Type,
+ PDiag(diag::err_delete_incomplete_class_type)))
+ return ExprError();
+
llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
@@ -1378,18 +1418,16 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
QualType ConvType = Conv->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
- if (ConvPtrType->getPointeeType()->isObjectType())
+ if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
ObjectPtrConversions.push_back(Conv);
}
if (ObjectPtrConversions.size() == 1) {
// We have a single conversion to a pointer-to-object type. Perform
// that conversion.
// TODO: don't redo the conversion calculation.
- Operand.release();
if (!PerformImplicitConversion(Ex,
ObjectPtrConversions.front()->getConversionType(),
AA_Converting)) {
- Operand = Owned(Ex);
Type = Ex->getType();
}
}
@@ -1428,16 +1466,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// (5.2.11) of the pointer expression before it is used as the operand
// of the delete-expression. ]
ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy),
- CastExpr::CK_NoOp);
-
- // Update the operand.
- Operand.take();
- Operand = ExprArg(*this, Ex);
+ CK_NoOp);
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
ArrayForm ? OO_Array_Delete : OO_Delete);
- if (const RecordType *RT = Pointee->getAs<RecordType>()) {
+ QualType PointeeElem = Context.getBaseElementType(Pointee);
+ if (const RecordType *RT = PointeeElem->getAs<RecordType>()) {
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (!UseGlobal &&
@@ -1465,14 +1500,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// FIXME: Check access and ambiguity of operator delete and destructor.
}
- Operand.release();
return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
OperatorDelete, Ex, StartLoc));
}
/// \brief Check the use of the given variable as a C++ condition in an if,
/// while, do-while, or switch statement.
-Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
+ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
SourceLocation StmtLoc,
bool ConvertToBoolean) {
QualType T = ConditionVar->getType();
@@ -1491,10 +1525,8 @@ Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
ConditionVar->getLocation(),
ConditionVar->getType().getNonReferenceType());
- if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc)) {
- Condition->Destroy(Context);
+ if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc))
return ExprError();
- }
return Owned(Condition);
}
@@ -1543,34 +1575,33 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
return false;
}
-static Sema::OwningExprResult BuildCXXCastArgument(Sema &S,
- SourceLocation CastLoc,
- QualType Ty,
- CastExpr::CastKind Kind,
- CXXMethodDecl *Method,
- Sema::ExprArg Arg) {
- Expr *From = Arg.takeAs<Expr>();
-
+static ExprResult BuildCXXCastArgument(Sema &S,
+ SourceLocation CastLoc,
+ QualType Ty,
+ CastKind Kind,
+ CXXMethodDecl *Method,
+ Expr *From) {
switch (Kind) {
default: assert(0 && "Unhandled cast kind!");
- case CastExpr::CK_ConstructorConversion: {
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+ case CK_ConstructorConversion: {
+ ASTOwningVector<Expr*> ConstructorArgs(S);
if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
- Sema::MultiExprArg(S, (void **)&From, 1),
+ MultiExprArg(&From, 1),
CastLoc, ConstructorArgs))
- return S.ExprError();
+ return ExprError();
- Sema::OwningExprResult Result =
+ ExprResult Result =
S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false, CXXConstructExpr::CK_Complete);
if (Result.isInvalid())
- return S.ExprError();
+ return ExprError();
return S.MaybeBindToTemporary(Result.takeAs<Expr>());
}
- case CastExpr::CK_UserDefinedConversion: {
+ case CK_UserDefinedConversion: {
assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
// Create an implicit call expr that calls it.
@@ -1601,10 +1632,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
case ImplicitConversionSequence::UserDefinedConversion: {
FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
- CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+ CastKind CastKind = CK_Unknown;
QualType BeforeToType;
if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
- CastKind = CastExpr::CK_UserDefinedConversion;
+ CastKind = CK_UserDefinedConversion;
// If the user-defined conversion is specified by a conversion function,
// the initial standard conversion sequence converts the source type to
@@ -1612,7 +1643,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
BeforeToType = Context.getTagDeclType(Conv->getParent());
} else if (const CXXConstructorDecl *Ctor =
dyn_cast<CXXConstructorDecl>(FD)) {
- CastKind = CastExpr::CK_ConstructorConversion;
+ CastKind = CK_ConstructorConversion;
// Do no conversion if dealing with ... for the first conversion.
if (!ICS.UserDefined.EllipsisConversion) {
// If the user-defined conversion is specified by a constructor, the
@@ -1631,12 +1662,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return true;
}
- OwningExprResult CastArg
+ ExprResult CastArg
= BuildCXXCastArgument(*this,
From->getLocStart(),
ToType.getNonReferenceType(),
CastKind, cast<CXXMethodDecl>(FD),
- Owned(From));
+ From);
if (CastArg.isInvalid())
return true;
@@ -1648,7 +1679,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
}
case ImplicitConversionSequence::AmbiguousConversion:
- DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+ ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
PDiag(diag::err_typecheck_ambiguous_condition)
<< From->getSourceRange());
return true;
@@ -1685,25 +1716,29 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
// FIXME: When can ToType be a reference type?
assert(!ToType->isReferenceType());
if (SCS.Second == ICK_Derived_To_Base) {
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+ ASTOwningVector<Expr*> ConstructorArgs(*this);
if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
- MultiExprArg(*this, (void **)&From, 1),
+ MultiExprArg(*this, &From, 1),
/*FIXME:ConstructLoc*/SourceLocation(),
ConstructorArgs))
return true;
- OwningExprResult FromResult =
+ ExprResult FromResult =
BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
if (FromResult.isInvalid())
return true;
From = FromResult.takeAs<Expr>();
return false;
}
- OwningExprResult FromResult =
+ ExprResult FromResult =
BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
- MultiExprArg(*this, (void**)&From, 1));
+ MultiExprArg(*this, &From, 1),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
if (FromResult.isInvalid())
return true;
@@ -1736,12 +1771,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
case ICK_Array_To_Pointer:
FromType = Context.getArrayDecayedType(FromType);
- ImpCastExprToType(From, FromType, CastExpr::CK_ArrayToPointerDecay);
+ ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay);
break;
case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType);
- ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);
+ ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay);
break;
default:
@@ -1766,33 +1801,33 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return true;
ImpCastExprToType(From, Context.getNoReturnType(From->getType(), false),
- CastExpr::CK_NoOp);
+ CK_NoOp);
break;
case ICK_Integral_Promotion:
case ICK_Integral_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(From, ToType, CK_IntegralCast);
break;
case ICK_Floating_Promotion:
case ICK_Floating_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_FloatingCast);
+ ImpCastExprToType(From, ToType, CK_FloatingCast);
break;
case ICK_Complex_Promotion:
case ICK_Complex_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+ ImpCastExprToType(From, ToType, CK_Unknown);
break;
case ICK_Floating_Integral:
if (ToType->isRealFloatingType())
- ImpCastExprToType(From, ToType, CastExpr::CK_IntegralToFloating);
+ ImpCastExprToType(From, ToType, CK_IntegralToFloating);
else
- ImpCastExprToType(From, ToType, CastExpr::CK_FloatingToIntegral);
+ ImpCastExprToType(From, ToType, CK_FloatingToIntegral);
break;
case ICK_Compatible_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_NoOp);
+ ImpCastExprToType(From, ToType, CK_NoOp);
break;
case ICK_Pointer_Conversion: {
@@ -1805,36 +1840,36 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
}
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
break;
}
case ICK_Pointer_Member: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
IgnoreBaseAccess))
return true;
if (CheckExceptionSpecCompatibility(From, ToType))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
break;
}
case ICK_Boolean_Conversion: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+ CastKind Kind = CK_Unknown;
if (FromType->isMemberPointerType())
- Kind = CastExpr::CK_MemberPointerToBoolean;
+ Kind = CK_MemberPointerToBoolean;
ImpCastExprToType(From, Context.BoolTy, Kind);
break;
}
case ICK_Derived_To_Base: {
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(From->getType(),
ToType.getNonReferenceType(),
From->getLocStart(),
@@ -1843,24 +1878,22 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType.getNonReferenceType(),
- CastExpr::CK_DerivedToBase,
- /*isLvalue=*/(From->getType()->isRecordType() &&
- From->isLvalue(Context) == Expr::LV_Valid),
- BasePath);
+ ImpCastExprToType(From, ToType.getNonReferenceType(),
+ CK_DerivedToBase, CastCategory(From),
+ &BasePath);
break;
}
case ICK_Vector_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_BitCast);
+ ImpCastExprToType(From, ToType, CK_BitCast);
break;
case ICK_Vector_Splat:
- ImpCastExprToType(From, ToType, CastExpr::CK_VectorSplat);
+ ImpCastExprToType(From, ToType, CK_VectorSplat);
break;
case ICK_Complex_Real:
- ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+ ImpCastExprToType(From, ToType, CK_Unknown);
break;
case ICK_Lvalue_To_Rvalue:
@@ -1877,18 +1910,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
// Nothing to do.
break;
- case ICK_Qualification:
- // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
- // references.
+ case ICK_Qualification: {
+ // The qualification keeps the category of the inner expression, unless the
+ // target type isn't a reference.
+ ExprValueKind VK = ToType->isReferenceType() ?
+ CastCategory(From) : VK_RValue;
ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
- CastExpr::CK_NoOp, ToType->isLValueReferenceType());
+ CK_NoOp, VK);
if (SCS.DeprecatedStringLiteralToCharPtr)
Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
<< ToType.getNonReferenceType();
break;
-
+ }
+
default:
assert(false && "Improper third standard conversion");
break;
@@ -1897,10 +1933,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return false;
}
-Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
SourceLocation KWLoc,
SourceLocation LParen,
- TypeTy *Ty,
+ ParsedType Ty,
SourceLocation RParen) {
QualType T = GetTypeFromParser(Ty);
@@ -1974,12 +2010,12 @@ QualType Sema::CheckPointerToMemberOperands(
}
// Cast LHS to type of use.
QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
- bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
-
- CXXBaseSpecifierArray BasePath;
+ ExprValueKind VK =
+ isIndirect ? VK_RValue : CastCategory(lex);
+
+ CXXCastPath BasePath;
BuildBasePathArray(Paths, BasePath);
- ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
- BasePath);
+ ImpCastExprToType(lex, UseType, CK_DerivedToBase, VK, &BasePath);
}
if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) {
@@ -2108,7 +2144,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
OverloadCandidateSet::iterator Best;
- switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(Self, Loc, Best)) {
case OR_Success:
// We found a match. Perform the conversions on the arguments and move on.
if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
@@ -2146,8 +2182,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) {
InitializationKind Kind = InitializationKind::CreateCopy(E->getLocStart(),
SourceLocation());
InitializationSequence InitSeq(Self, Entity, Kind, &E, 1);
- Sema::OwningExprResult Result = InitSeq.Perform(Self, Entity, Kind,
- Sema::MultiExprArg(Self, (void **)&E, 1));
+ ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&E, 1));
if (Result.isInvalid())
return true;
@@ -2286,13 +2321,13 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (LTy->isRecordType()) {
// The operands have class type. Make a temporary copy.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
- OwningExprResult LHSCopy = PerformCopyInitialization(Entity,
+ ExprResult LHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(LHS));
if (LHSCopy.isInvalid())
return QualType();
- OwningExprResult RHSCopy = PerformCopyInitialization(Entity,
+ ExprResult RHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(RHS));
if (RHSCopy.isInvalid())
@@ -2385,16 +2420,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// the type of the other operand.
if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T2->isMemberPointerType())
- ImpCastExprToType(E1, T2, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(E1, T2, CK_NullToMemberPointer);
else
- ImpCastExprToType(E1, T2, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(E1, T2, CK_IntegralToPointer);
return T2;
}
if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T1->isMemberPointerType())
- ImpCastExprToType(E2, T1, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(E2, T1, CK_NullToMemberPointer);
else
- ImpCastExprToType(E2, T1, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(E2, T1, CK_IntegralToPointer);
return T1;
}
@@ -2528,15 +2563,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
}
// Convert E1 to Composite1
- OwningExprResult E1Result
- = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+ ExprResult E1Result
+ = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E1,1));
if (E1Result.isInvalid())
return QualType();
E1 = E1Result.takeAs<Expr>();
// Convert E2 to Composite1
- OwningExprResult E2Result
- = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E2,1));
+ ExprResult E2Result
+ = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1));
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
@@ -2553,15 +2588,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return QualType();
// Convert E1 to Composite2
- OwningExprResult E1Result
- = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+ ExprResult E1Result
+ = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1));
if (E1Result.isInvalid())
return QualType();
E1 = E1Result.takeAs<Expr>();
// Convert E2 to Composite2
- OwningExprResult E2Result
- = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E2, 1));
+ ExprResult E2Result
+ = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1));
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
@@ -2569,7 +2604,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return Composite2;
}
-Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
+ExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!Context.getLangOptions().CPlusPlus)
return Owned(E);
@@ -2579,34 +2614,22 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!RT)
return Owned(E);
- // If this is the result of a call expression, our source might
- // actually be a reference, in which case we shouldn't bind.
+ // If this is the result of a call or an Objective-C message send expression,
+ // our source might actually be a reference, in which case we shouldn't bind.
if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
- QualType Ty = CE->getCallee()->getType();
- if (const PointerType *PT = Ty->getAs<PointerType>())
- Ty = PT->getPointeeType();
- else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
- Ty = BPT->getPointeeType();
-
- const FunctionType *FTy = Ty->getAs<FunctionType>();
- if (FTy->getResultType()->isReferenceType())
+ if (CE->getCallReturnType()->isReferenceType())
return Owned(E);
+ } else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
+ if (MD->getResultType()->isReferenceType())
+ return Owned(E);
+ }
}
- else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
- QualType Ty = ME->getType();
- if (const PointerType *PT = Ty->getAs<PointerType>())
- Ty = PT->getPointeeType();
- else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
- Ty = BPT->getPointeeType();
- if (Ty->isReferenceType())
- return Owned(E);
- }
-
// That should be enough to guarantee that this type is complete.
// If it has a trivial destructor, we can avoid the extra copy.
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->hasTrivialDestructor())
+ if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
return Owned(E);
CXXTemporary *Temp = CXXTemporary::Create(Context, LookupDestructor(RD));
@@ -2641,8 +2664,8 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
return E;
}
-Sema::OwningExprResult
-Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+ExprResult
+Sema::MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr) {
if (SubExpr.isInvalid())
return ExprError();
@@ -2665,17 +2688,16 @@ FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
return E;
}
-Sema::OwningExprResult
-Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
- tok::TokenKind OpKind, TypeTy *&ObjectType,
+ExprResult
+Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
+ tok::TokenKind OpKind, ParsedType &ObjectType,
bool &MayBePseudoDestructor) {
// Since this might be a postfix expression, get rid of ParenListExprs.
- Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.get();
- Expr *BaseExpr = (Expr*)Base.get();
- assert(BaseExpr && "no record expansion");
-
- QualType BaseType = BaseExpr->getType();
+ QualType BaseType = Base->getType();
MayBePseudoDestructor = false;
if (BaseType->isDependentType()) {
// If we have a pointer to a dependent type and are using the -> operator,
@@ -2685,9 +2707,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (const PointerType *Ptr = BaseType->getAs<PointerType>())
BaseType = Ptr->getPointeeType();
- ObjectType = BaseType.getAsOpaquePtr();
+ ObjectType = ParsedType::make(BaseType);
MayBePseudoDestructor = true;
- return move(Base);
+ return Owned(Base);
}
// C++ [over.match.oper]p8:
@@ -2700,13 +2722,13 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
CTypes.insert(Context.getCanonicalType(BaseType));
while (BaseType->isRecordType()) {
- Base = BuildOverloadedArrowExpr(S, move(Base), OpLoc);
- BaseExpr = (Expr*)Base.get();
- if (BaseExpr == NULL)
+ Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
+ if (Result.isInvalid())
return ExprError();
- if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+ Base = Result.get();
+ if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
Locations.push_back(OpCall->getDirectCallee()->getLocation());
- BaseType = BaseExpr->getType();
+ BaseType = Base->getType();
CanQualType CBaseType = Context.getCanonicalType(BaseType);
if (!CTypes.insert(CBaseType)) {
Diag(OpLoc, diag::err_operator_arrow_circular);
@@ -2731,9 +2753,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
//
// This also indicates that we should be parsing a
// pseudo-destructor-name.
- ObjectType = 0;
+ ObjectType = ParsedType();
MayBePseudoDestructor = true;
- return move(Base);
+ return Owned(Base);
}
// The object type must be complete (or dependent).
@@ -2747,27 +2769,26 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
// unqualified-id, and the type of the object expression is of a class
// type C (or of pointer to a class type C), the unqualified-id is looked
// up in the scope of class C. [...]
- ObjectType = BaseType.getAsOpaquePtr();
+ ObjectType = ParsedType::make(BaseType);
return move(Base);
}
-Sema::OwningExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
- ExprArg MemExpr) {
- Expr *E = (Expr *) MemExpr.get();
+ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
+ Expr *MemExpr) {
SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc);
- Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
- << isa<CXXPseudoDestructorExpr>(E)
+ Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call)
+ << isa<CXXPseudoDestructorExpr>(MemExpr)
<< FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
return ActOnCallExpr(/*Scope*/ 0,
- move(MemExpr),
+ MemExpr,
/*LPLoc*/ ExpectedLParenLoc,
- Sema::MultiExprArg(*this, 0, 0),
+ MultiExprArg(),
/*CommaLocs*/ 0,
/*RPLoc*/ ExpectedLParenLoc);
}
-Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
+ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
const CXXScopeSpec &SS,
@@ -2782,12 +2803,11 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
// The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
// This scalar type is the object type.
- Expr *BaseE = (Expr *)Base.get();
- QualType ObjectType = BaseE->getType();
+ QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
- } else if (!BaseE->isTypeDependent()) {
+ } else if (!Base->isTypeDependent()) {
// The user wrote "p->" when she probably meant "p."; fix it.
Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< ObjectType << true
@@ -2801,7 +2821,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
- << ObjectType << BaseE->getSourceRange();
+ << ObjectType << Base->getSourceRange();
return ExprError();
}
@@ -2815,7 +2835,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
if (!DestructedType->isDependentType() && !ObjectType->isDependentType() &&
!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
- << ObjectType << DestructedType << BaseE->getSourceRange()
+ << ObjectType << DestructedType << Base->getSourceRange()
<< DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
// Recover by setting the destructed type to the object type.
@@ -2840,7 +2860,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(),
diag::err_pseudo_dtor_type_mismatch)
- << ObjectType << ScopeType << BaseE->getSourceRange()
+ << ObjectType << ScopeType << Base->getSourceRange()
<< ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
ScopeType = QualType();
@@ -2848,25 +2868,22 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
}
}
- OwningExprResult Result
- = Owned(new (Context) CXXPseudoDestructorExpr(Context,
- Base.takeAs<Expr>(),
- OpKind == tok::arrow,
- OpLoc,
- (NestedNameSpecifier *) SS.getScopeRep(),
- SS.getRange(),
- ScopeTypeInfo,
- CCLoc,
- TildeLoc,
- Destructed));
+ Expr *Result
+ = new (Context) CXXPseudoDestructorExpr(Context, Base,
+ OpKind == tok::arrow, OpLoc,
+ SS.getScopeRep(), SS.getRange(),
+ ScopeTypeInfo,
+ CCLoc,
+ TildeLoc,
+ Destructed);
if (HasTrailingLParen)
- return move(Result);
+ return Owned(Result);
- return DiagnoseDtorReference(Destructed.getLocation(), move(Result));
+ return DiagnoseDtorReference(Destructed.getLocation(), Result);
}
-Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
CXXScopeSpec &SS,
@@ -2882,13 +2899,11 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
"Invalid second type name in pseudo-destructor");
- Expr *BaseE = (Expr *)Base.get();
-
// C++ [expr.pseudo]p2:
// The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
// This scalar type is the object type.
- QualType ObjectType = BaseE->getType();
+ QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
@@ -2906,12 +2921,12 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
// Compute the object type that we should use for name lookup purposes. Only
// record types and dependent types matter.
- void *ObjectTypePtrForLookup = 0;
+ ParsedType ObjectTypePtrForLookup;
if (!SS.isSet()) {
- ObjectTypePtrForLookup = const_cast<RecordType*>(
- ObjectType->getAs<RecordType>());
- if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
- ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+ if (const Type *T = ObjectType->getAs<RecordType>())
+ ObjectTypePtrForLookup = ParsedType::make(QualType(T, 0));
+ else if (ObjectType->isDependentType())
+ ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
}
// Convert the name of the type being destructed (following the ~) into a
@@ -2920,9 +2935,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
TypeSourceInfo *DestructedTypeInfo = 0;
PseudoDestructorTypeStorage Destructed;
if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- TypeTy *T = getTypeName(*SecondTypeName.Identifier,
- SecondTypeName.StartLocation,
- S, &SS, true, ObjectTypePtrForLookup);
+ ParsedType T = getTypeName(*SecondTypeName.Identifier,
+ SecondTypeName.StartLocation,
+ S, &SS, true, ObjectTypePtrForLookup);
if (!T &&
((SS.isSet() && !computeDeclContext(SS, false)) ||
(!SS.isSet() && ObjectType->isDependentType()))) {
@@ -2949,7 +2964,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+ TypeResult T = ActOnTemplateIdType(TemplateId->Template,
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
@@ -2976,9 +2991,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
FirstTypeName.Identifier) {
if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- TypeTy *T = getTypeName(*FirstTypeName.Identifier,
- FirstTypeName.StartLocation,
- S, &SS, false, ObjectTypePtrForLookup);
+ ParsedType T = getTypeName(*FirstTypeName.Identifier,
+ FirstTypeName.StartLocation,
+ S, &SS, false, ObjectTypePtrForLookup);
if (!T) {
Diag(FirstTypeName.StartLocation,
diag::err_pseudo_dtor_destructor_non_type)
@@ -2997,7 +3012,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+ TypeResult T = ActOnTemplateIdType(TemplateId->Template,
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
@@ -3015,7 +3030,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
FirstTypeName.StartLocation);
- return BuildPseudoDestructorExpr(move(Base), OpLoc, OpKind, SS,
+ return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
ScopeTypeInfo, CCLoc, TildeLoc,
Destructed, HasTrailingLParen);
}
@@ -3028,7 +3043,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
MemberExpr *ME =
- new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
+ new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
SourceLocation(), Method->getType());
QualType ResultType = Method->getCallResultType();
MarkDeclarationReferenced(Exp->getLocStart(), Method);
@@ -3038,12 +3053,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
return CE;
}
-Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
- Expr *FullExpr = Arg.takeAs<Expr>();
- if (FullExpr)
- FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
- else
- return ExprError();
-
- return Owned(FullExpr);
+ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
+ if (!FullExpr) return ExprError();
+ return MaybeCreateCXXExprWithTemporaries(FullExpr);
}
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 9f43471e0ade..b56159c453b5 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
@@ -23,9 +24,9 @@
using namespace clang;
-Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
- ExprTy **strings,
- unsigned NumStrings) {
+ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
+ Expr **strings,
+ unsigned NumStrings) {
StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
// Most ObjC strings are formed out of a single piece. However, we *can*
@@ -50,14 +51,11 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
return true;
}
- // Get the string data.
- StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
+ // Append the string.
+ StrBuf += S->getString();
// Get the locations of the string tokens.
StrLocs.append(S->tokloc_begin(), S->tokloc_end());
-
- // Free the temporary string.
- S->Destroy(Context);
}
// Create the aggregate string with the appropriate content and location
@@ -135,11 +133,11 @@ Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
}
-Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
- SourceLocation EncodeLoc,
- SourceLocation LParenLoc,
- TypeTy *ty,
- SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
+ SourceLocation EncodeLoc,
+ SourceLocation LParenLoc,
+ ParsedType ty,
+ SourceLocation RParenLoc) {
// FIXME: Preserve type source info ?
TypeSourceInfo *TInfo;
QualType EncodedType = GetTypeFromParser(ty, &TInfo);
@@ -150,28 +148,33 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
}
-Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
- SourceLocation AtLoc,
- SourceLocation SelLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+ SourceLocation AtLoc,
+ SourceLocation SelLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
- SourceRange(LParenLoc, RParenLoc), false);
+ SourceRange(LParenLoc, RParenLoc), false, false);
if (!Method)
Method = LookupFactoryMethodInGlobalPool(Sel,
SourceRange(LParenLoc, RParenLoc));
if (!Method)
Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
+ llvm::DenseMap<Selector, SourceLocation>::iterator Pos
+ = ReferencedSelectors.find(Sel);
+ if (Pos == ReferencedSelectors.end())
+ ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
+
QualType Ty = Context.getObjCSelType();
return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
}
-Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
- SourceLocation AtLoc,
- SourceLocation ProtoLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+ SourceLocation AtLoc,
+ SourceLocation ProtoLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoLoc);
if (!PDecl) {
Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
@@ -239,7 +242,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
return true;
InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
- OwningExprResult ArgE = PerformCopyInitialization(Entity,
+ ExprResult ArgE = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(argExpr->Retain()));
if (ArgE.isInvalid())
@@ -329,7 +332,7 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
/// objective C interface. This is a property reference expression.
-Action::OwningExprResult Sema::
+ExprResult Sema::
HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
Expr *BaseExpr, DeclarationName MemberName,
SourceLocation MemberLoc) {
@@ -431,7 +434,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
-Action::OwningExprResult Sema::
+ExprResult Sema::
ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
IdentifierInfo &propertyName,
SourceLocation receiverNameLoc,
@@ -529,8 +532,8 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
SourceLocation NameLoc,
bool IsSuper,
bool HasTrailingDot,
- TypeTy *&ReceiverType) {
- ReceiverType = 0;
+ ParsedType &ReceiverType) {
+ ReceiverType = ParsedType();
// If the identifier is "super" and there is no trailing dot, we're
// messaging super.
@@ -577,7 +580,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
// We have a class message, and T is the type we're
// messaging. Build source-location information for it.
TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
- ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+ ReceiverType = CreateParsedType(T, TSInfo);
return ObjCClassMessage;
}
}
@@ -604,7 +607,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
QualType T = Context.getObjCInterfaceType(Class);
TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
- ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+ ReceiverType = CreateParsedType(T, TSInfo);
return ObjCClassMessage;
}
} else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
@@ -622,7 +625,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
return ObjCInstanceMessage;
}
-Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S,
+ExprResult Sema::ActOnSuperMessage(Scope *S,
SourceLocation SuperLoc,
Selector Sel,
SourceLocation LBracLoc,
@@ -657,7 +660,7 @@ Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S,
// message to the superclass instance.
QualType SuperTy = Context.getObjCInterfaceType(Super);
SuperTy = Context.getObjCObjectPointerType(SuperTy);
- return BuildInstanceMessage(ExprArg(*this), SuperTy, SuperLoc,
+ return BuildInstanceMessage(0, SuperTy, SuperLoc,
Sel, /*Method=*/0, LBracLoc, RBracLoc,
move(Args));
}
@@ -698,7 +701,7 @@ Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S,
/// \param RBrac The location of the closing square bracket ']'.
///
/// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
QualType ReceiverType,
SourceLocation SuperLoc,
Selector Sel,
@@ -757,11 +760,8 @@ Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true,
- LBracLoc, RBracLoc, ReturnType)) {
- for (unsigned I = 0; I != NumArgs; ++I)
- Args[I]->Destroy(Context);
+ LBracLoc, RBracLoc, ReturnType))
return ExprError();
- }
// Construct the appropriate ObjCMessageExpr.
Expr *Result;
@@ -780,8 +780,8 @@ Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
-Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S,
- TypeTy *Receiver,
+ExprResult Sema::ActOnClassMessage(Scope *S,
+ ParsedType Receiver,
Selector Sel,
SourceLocation LBracLoc,
SourceLocation SelectorLoc,
@@ -829,7 +829,7 @@ Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S,
/// \param RBrac The location of the closing square bracket ']'.
///
/// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
+ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
QualType ReceiverType,
SourceLocation SuperLoc,
Selector Sel,
@@ -839,7 +839,6 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
MultiExprArg ArgsIn) {
// If we have a receiver expression, perform appropriate promotions
// and determine receiver type.
- Expr *Receiver = ReceiverE.takeAs<Expr>();
if (Receiver) {
if (Receiver->isTypeDependent()) {
// If the receiver is type-dependent, we can't type-check anything
@@ -864,13 +863,16 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
if (!Method) {
// Handle messages to id.
- if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType() ||
+ bool receiverIsId = ReceiverType->isObjCIdType();
+ if (receiverIsId || ReceiverType->isBlockPointerType() ||
(Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
Method = LookupInstanceMethodInGlobalPool(Sel,
- SourceRange(LBracLoc, RBracLoc));
+ SourceRange(LBracLoc, RBracLoc),
+ receiverIsId);
if (!Method)
Method = LookupFactoryMethodInGlobalPool(Sel,
- SourceRange(LBracLoc, RBracLoc));
+ SourceRange(LBracLoc, RBracLoc),
+ receiverIsId);
} else if (ReceiverType->isObjCClassType() ||
ReceiverType->isObjCQualifiedClassType()) {
// Handle messages to Class.
@@ -892,12 +894,14 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
// If not messaging 'self', look for any factory method named 'Sel'.
if (!Receiver || !isSelfExpr(Receiver)) {
Method = LookupFactoryMethodInGlobalPool(Sel,
- SourceRange(LBracLoc, RBracLoc));
+ SourceRange(LBracLoc, RBracLoc),
+ true);
if (!Method) {
// If no class (factory) method was found, check if an _instance_
// method of the same name exists in the root class only.
Method = LookupInstanceMethodInGlobalPool(Sel,
- SourceRange(LBracLoc, RBracLoc));
+ SourceRange(LBracLoc, RBracLoc),
+ true);
if (Method)
if (const ObjCInterfaceDecl *ID =
dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
@@ -931,7 +935,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
ClassDecl = OCIType->getInterfaceDecl();
// FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
// faster than the following method (which can do *many* linear searches).
- // The idea is to add class info to InstanceMethodPool.
+ // The idea is to add class info to MethodPool.
Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method) {
@@ -952,7 +956,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
// compatibility. FIXME: should we deviate??
if (OCIType->qual_empty()) {
Method = LookupInstanceMethodInGlobalPool(Sel,
- SourceRange(LBracLoc, RBracLoc));
+ SourceRange(LBracLoc, RBracLoc));
if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
Diag(Loc, diag::warn_maynot_respond)
<< OCIType->getInterfaceDecl()->getIdentifier() << Sel;
@@ -962,19 +966,18 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
if (Method && DiagnoseUseOfDecl(Method, Loc))
return ExprError();
} else if (!Context.getObjCIdType().isNull() &&
- (ReceiverType->isPointerType() ||
- (ReceiverType->isIntegerType() &&
- ReceiverType->isScalarType()))) {
+ (ReceiverType->isPointerType() ||
+ ReceiverType->isIntegerType())) {
// Implicitly convert integers and pointers to 'id' but emit a warning.
Diag(Loc, diag::warn_bad_receiver_type)
<< ReceiverType
<< Receiver->getSourceRange();
if (ReceiverType->isPointerType())
ImpCastExprToType(Receiver, Context.getObjCIdType(),
- CastExpr::CK_BitCast);
+ CK_BitCast);
else
ImpCastExprToType(Receiver, Context.getObjCIdType(),
- CastExpr::CK_IntegralToPointer);
+ CK_IntegralToPointer);
ReceiverType = Receiver->getType();
}
else if (getLangOptions().CPlusPlus &&
@@ -983,7 +986,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
Receiver = ICE->getSubExpr();
ReceiverType = Receiver->getType();
}
- return BuildInstanceMessage(Owned(Receiver),
+ return BuildInstanceMessage(Receiver,
ReceiverType,
SuperLoc,
Sel,
@@ -1030,18 +1033,17 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
// ActOnInstanceMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
-Sema::OwningExprResult Sema::ActOnInstanceMessage(Scope *S,
- ExprArg ReceiverE,
- Selector Sel,
- SourceLocation LBracLoc,
- SourceLocation SelectorLoc,
- SourceLocation RBracLoc,
- MultiExprArg Args) {
- Expr *Receiver = static_cast<Expr *>(ReceiverE.get());
+ExprResult Sema::ActOnInstanceMessage(Scope *S,
+ Expr *Receiver,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
if (!Receiver)
return ExprError();
- return BuildInstanceMessage(move(ReceiverE), Receiver->getType(),
+ return BuildInstanceMessage(Receiver, Receiver->getType(),
/*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
LBracLoc, RBracLoc, move(Args));
}
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7ad177557ef4..a28fd7fe12bd 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -15,12 +15,13 @@
//
//===----------------------------------------------------------------------===//
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "Sema.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/SemaInternal.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Designator.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
@@ -263,9 +264,8 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
return;
}
- Sema::OwningExprResult MemberInit
- = InitSeq.Perform(SemaRef, MemberEntity, Kind,
- Sema::MultiExprArg(SemaRef, 0, 0));
+ ExprResult MemberInit
+ = InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg());
if (MemberInit.isInvalid()) {
hadError = true;
return;
@@ -373,9 +373,8 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
return;
}
- Sema::OwningExprResult ElementInit
- = InitSeq.Perform(SemaRef, ElementEntity, Kind,
- Sema::MultiExprArg(SemaRef, 0, 0));
+ ExprResult ElementInit
+ = InitSeq.Perform(SemaRef, ElementEntity, Kind, MultiExprArg());
if (ElementInit.isInvalid()) {
hadError = true;
return;
@@ -678,9 +677,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
if (Seq) {
- Sema::OwningExprResult Result =
- Seq.Perform(SemaRef, Entity, Kind,
- Sema::MultiExprArg(SemaRef, (void **)&expr, 1));
+ ExprResult Result =
+ Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
if (Result.isInvalid())
hadError = true;
@@ -740,13 +738,13 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
unsigned &StructuredIndex) {
if (Index < IList->getNumInits()) {
Expr *expr = IList->getInit(Index);
- if (isa<InitListExpr>(expr)) {
- SemaRef.Diag(IList->getLocStart(),
- diag::err_many_braces_around_scalar_init)
- << IList->getSourceRange();
- hadError = true;
- ++Index;
- ++StructuredIndex;
+ if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) {
+ SemaRef.Diag(SubIList->getLocStart(),
+ diag::warn_many_braces_around_scalar_init)
+ << SubIList->getSourceRange();
+
+ CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
+ StructuredIndex);
return;
} else if (isa<DesignatedInitExpr>(expr)) {
SemaRef.Diag(expr->getSourceRange().getBegin(),
@@ -758,7 +756,7 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
return;
}
- Sema::OwningExprResult Result =
+ ExprResult Result =
SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
SemaRef.Owned(expr));
@@ -805,7 +803,7 @@ void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
return;
}
- Sema::OwningExprResult Result =
+ ExprResult Result =
SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
SemaRef.Owned(expr));
@@ -1367,7 +1365,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false,
Sema::CTC_NoKeywords) &&
(ReplacementField = R.getAsSingle<FieldDecl>()) &&
- ReplacementField->getDeclContext()->getLookupContext()
+ ReplacementField->getDeclContext()->getRedeclContext()
->Equals(RT->getDecl())) {
SemaRef.Diag(D->getFieldLoc(),
diag::err_field_designator_unknown_suggest)
@@ -1813,10 +1811,10 @@ CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
return false;
}
-Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
+ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
SourceLocation Loc,
bool GNUSyntax,
- OwningExprResult Init) {
+ ExprResult Init) {
typedef DesignatedInitExpr::Designator ASTDesignator;
bool Invalid = false;
@@ -2021,18 +2019,21 @@ void InitializationSequence::Step::Destroy() {
switch (Kind) {
case SK_ResolveAddressOfOverloadedFunction:
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue:
case SK_BindReference:
case SK_BindReferenceToTemporary:
case SK_ExtraneousCopyToTemporary:
case SK_UserConversion:
case SK_QualificationConversionRValue:
+ case SK_QualificationConversionXValue:
case SK_QualificationConversionLValue:
case SK_ListInitialization:
case SK_ConstructorInitialization:
case SK_ZeroInitialization:
case SK_CAssignment:
case SK_StringInit:
+ case SK_ObjCObjectConversion:
break;
case SK_ConversionSequence:
@@ -2091,9 +2092,14 @@ void InitializationSequence::AddAddressOverloadResolutionStep(
}
void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType,
- bool IsLValue) {
+ ExprValueKind VK) {
Step S;
- S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+ switch (VK) {
+ case VK_RValue: S.Kind = SK_CastDerivedToBaseRValue; break;
+ case VK_XValue: S.Kind = SK_CastDerivedToBaseXValue; break;
+ case VK_LValue: S.Kind = SK_CastDerivedToBaseLValue; break;
+ default: llvm_unreachable("No such category");
+ }
S.Type = BaseType;
Steps.push_back(S);
}
@@ -2125,10 +2131,20 @@ void InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
}
void InitializationSequence::AddQualificationConversionStep(QualType Ty,
- bool IsLValue) {
+ ExprValueKind VK) {
Step S;
- S.Kind = IsLValue? SK_QualificationConversionLValue
- : SK_QualificationConversionRValue;
+ S.Kind = SK_QualificationConversionRValue; // work around a gcc warning
+ switch (VK) {
+ case VK_RValue:
+ S.Kind = SK_QualificationConversionRValue;
+ break;
+ case VK_XValue:
+ S.Kind = SK_QualificationConversionXValue;
+ break;
+ case VK_LValue:
+ S.Kind = SK_QualificationConversionLValue;
+ break;
+ }
S.Type = Ty;
Steps.push_back(S);
}
@@ -2184,6 +2200,13 @@ void InitializationSequence::AddStringInitStep(QualType T) {
Steps.push_back(S);
}
+void InitializationSequence::AddObjCObjectConversionStep(QualType T) {
+ Step S;
+ S.Kind = SK_ObjCObjectConversion;
+ S.Type = T;
+ Steps.push_back(S);
+}
+
void InitializationSequence::SetOverloadFailure(FailureKind Failure,
OverloadingResult Result) {
SequenceKind = FailedSequence;
@@ -2258,10 +2281,13 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
QualType T2 = cv2T2.getUnqualifiedType();
bool DerivedToBase;
+ bool ObjCConversion;
assert(!S.CompareReferenceRelationship(Initializer->getLocStart(),
- T1, T2, DerivedToBase) &&
+ T1, T2, DerivedToBase,
+ ObjCConversion) &&
"Must have incompatible references when binding via conversion");
(void)DerivedToBase;
+ (void)ObjCConversion;
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
@@ -2278,6 +2304,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
// The type we're converting to is a class type. Enumerate its constructors
// to see if there is a suitable conversion.
CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = S.LookupConstructors(T1RecordDecl);
Con != ConEnd; ++Con) {
@@ -2305,6 +2332,8 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
}
}
}
+ if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
+ return OR_No_Viable_Function;
const RecordType *T2RecordType = 0;
if ((T2RecordType = T2->getAs<RecordType>()) &&
@@ -2352,13 +2381,15 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
}
}
}
+ if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
+ return OR_No_Viable_Function;
SourceLocation DeclLoc = Initializer->getLocStart();
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best))
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best))
return Result;
FunctionDecl *Function = Best->Function;
@@ -2375,11 +2406,18 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
// Determine whether we need to perform derived-to-base or
// cv-qualification adjustments.
+ ExprValueKind VK = VK_RValue;
+ if (T2->isLValueReferenceType())
+ VK = VK_LValue;
+ else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>())
+ VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
+
bool NewDerivedToBase = false;
+ bool NewObjCConversion = false;
Sema::ReferenceCompareResult NewRefRelationship
= S.CompareReferenceRelationship(DeclLoc, T1,
T2.getNonLValueExprType(S.Context),
- NewDerivedToBase);
+ NewDerivedToBase, NewObjCConversion);
if (NewRefRelationship == Sema::Ref_Incompatible) {
// If the type we've converted to is not reference-related to the
// type we're looking for, then there is another conversion step
@@ -2394,10 +2432,14 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1,
T2.getNonReferenceType().getQualifiers()),
- /*isLValue=*/true);
-
+ VK);
+ else if (NewObjCConversion)
+ Sequence.AddObjCObjectConversionStep(
+ S.Context.getQualifiedType(T1,
+ T2.getNonReferenceType().getQualifiers()));
+
if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
- Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+ Sequence.AddQualificationConversionStep(cv1T1, VK);
Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
return OR_Success;
@@ -2443,9 +2485,11 @@ static void TryReferenceInitialization(Sema &S,
bool isLValueRef = DestType->isLValueReferenceType();
bool isRValueRef = !isLValueRef;
bool DerivedToBase = false;
+ bool ObjCConversion = false;
Expr::Classification InitCategory = Initializer->Classify(S.Context);
Sema::ReferenceCompareResult RefRelationship
- = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
+ = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase,
+ ObjCConversion);
// C++0x [dcl.init.ref]p5:
// A reference to type "cv1 T1" is initialized by an expression of type
@@ -2472,9 +2516,13 @@ static void TryReferenceInitialization(Sema &S,
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1, T2Quals),
- /*isLValue=*/true);
+ VK_LValue);
+ else if (ObjCConversion)
+ Sequence.AddObjCObjectConversionStep(
+ S.Context.getQualifiedType(T1, T2Quals));
+
if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+ Sequence.AddQualificationConversionStep(cv1T1, VK_LValue);
bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
(Initializer->getBitField() || Initializer->refersToVectorElement());
Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
@@ -2531,6 +2579,7 @@ static void TryReferenceInitialization(Sema &S,
// - [If T1 is not a function type], if T2 is a class type and
if (!T1Function && T2->isRecordType()) {
+ bool isXValue = InitCategory.isXValue();
// - the initializer expression is an rvalue and "cv1 T1" is
// reference-compatible with "cv2 T2", or
if (InitCategory.isRValue() &&
@@ -2550,10 +2599,15 @@ static void TryReferenceInitialization(Sema &S,
if (DerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1, T2Quals),
- /*isLValue=*/false);
+ isXValue ? VK_XValue : VK_RValue);
+ else if (ObjCConversion)
+ Sequence.AddObjCObjectConversionStep(
+ S.Context.getQualifiedType(T1, T2Quals));
+
if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
- Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+ Sequence.AddQualificationConversionStep(cv1T1,
+ isXValue ? VK_XValue : VK_RValue);
+ Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue);
return;
}
@@ -2717,7 +2771,7 @@ static void TryConstructorInitialization(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_ConstructorOverloadFailed,
Result);
@@ -2803,8 +2857,8 @@ static void TryDefaultInitialization(Sema &S,
// constructor for T is called (and the initialization is ill-formed if
// T has no accessible default constructor);
if (DestType->isRecordType() && S.getLangOptions().CPlusPlus) {
- return TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType,
- Sequence);
+ TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence);
+ return;
}
// - otherwise, no initialization is performed.
@@ -2927,7 +2981,7 @@ static void TryUserDefinedConversion(Sema &S,
// Perform overload resolution. If it fails, return the failed result.
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
- = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+ = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
Sequence.SetOverloadFailure(
InitializationSequence::FK_UserConversionOverloadFailed,
Result);
@@ -2969,24 +3023,6 @@ static void TryUserDefinedConversion(Sema &S,
}
}
-bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
- const InitializedEntity &Entity,
- Expr *Initializer,
- bool SuppressUserConversions,
- bool AllowExplicitConversions,
- bool InOverloadResolution) {
- ImplicitConversionSequence ICS
- = TryImplicitConversion(Initializer, Entity.getType(),
- SuppressUserConversions,
- AllowExplicitConversions,
- InOverloadResolution);
- if (ICS.isBad()) return true;
-
- // Perform the actual conversion.
- Sequence.AddConversionSequenceStep(ICS, Entity.getType());
- return false;
-}
-
InitializationSequence::InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
@@ -3239,10 +3275,10 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
/// \returns An expression that copies the initializer expression into
/// a temporary object, or an error expression if a copy could not be
/// created.
-static Sema::OwningExprResult CopyObject(Sema &S,
+static ExprResult CopyObject(Sema &S,
QualType T,
const InitializedEntity &Entity,
- Sema::OwningExprResult CurInit,
+ ExprResult CurInit,
bool IsExtraneousCopy) {
// Determine which class type we're copying to.
Expr *CurInitExpr = (Expr *)CurInit.get();
@@ -3318,7 +3354,7 @@ static Sema::OwningExprResult CopyObject(Sema &S,
}
OverloadCandidateSet::iterator Best;
- switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
case OR_Success:
break;
@@ -3328,19 +3364,17 @@ static Sema::OwningExprResult CopyObject(Sema &S,
: diag::err_temp_copy_no_viable)
<< (int)Entity.getKind() << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
- S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates,
- &CurInitExpr, 1);
+ CandidateSet.NoteCandidates(S, OCD_AllCandidates, &CurInitExpr, 1);
if (!IsExtraneousCopy || S.isSFINAEContext())
- return S.ExprError();
+ return ExprError();
return move(CurInit);
case OR_Ambiguous:
S.Diag(Loc, diag::err_temp_copy_ambiguous)
<< (int)Entity.getKind() << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
- S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates,
- &CurInitExpr, 1);
- return S.ExprError();
+ CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1);
+ return ExprError();
case OR_Deleted:
S.Diag(Loc, diag::err_temp_copy_deleted)
@@ -3348,11 +3382,11 @@ static Sema::OwningExprResult CopyObject(Sema &S,
<< CurInitExpr->getSourceRange();
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
<< Best->Function->isDeleted();
- return S.ExprError();
+ return ExprError();
}
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+ ASTOwningVector<Expr*> ConstructorArgs(S);
CurInit.release(); // Ownership transferred into MultiExprArg, below.
S.CheckConstructorAccess(Loc, Constructor, Entity,
@@ -3387,16 +3421,15 @@ static Sema::OwningExprResult CopyObject(Sema &S,
// Determine the arguments required to actually perform the
// constructor call (we might have derived-to-base conversions, or
// the copy constructor may have default arguments).
- if (S.CompleteConstructorCall(Constructor,
- Sema::MultiExprArg(S,
- (void **)&CurInitExpr,
- 1),
+ if (S.CompleteConstructorCall(Constructor, MultiExprArg(&CurInitExpr, 1),
Loc, ConstructorArgs))
- return S.ExprError();
+ return ExprError();
// Actually perform the constructor call.
CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
// If we're supposed to bind temporaries, do so.
if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
@@ -3418,16 +3451,16 @@ void InitializationSequence::PrintInitLocationNote(Sema &S,
}
}
-Action::OwningExprResult
+ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- Action::MultiExprArg Args,
+ MultiExprArg Args,
QualType *ResultType) {
if (SequenceKind == FailedSequence) {
unsigned NumArgs = Args.size();
Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
- return S.ExprError();
+ return ExprError();
}
if (SequenceKind == DependentSequence) {
@@ -3471,7 +3504,7 @@ InitializationSequence::Perform(Sema &S,
}
if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
- return Sema::OwningExprResult(S, Args.release()[0]);
+ return ExprResult(Args.release()[0]);
if (Args.size() == 0)
return S.Owned((Expr *)0);
@@ -3495,7 +3528,7 @@ InitializationSequence::Perform(Sema &S,
*ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
Entity.getType();
- Sema::OwningExprResult CurInit = S.Owned((Expr *)0);
+ ExprResult CurInit = S.Owned((Expr *)0);
assert(!Steps.empty() && "Cannot have an empty initialization sequence");
@@ -3505,21 +3538,24 @@ InitializationSequence::Perform(Sema &S,
switch (Steps.front().Kind) {
case SK_ResolveAddressOfOverloadedFunction:
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue:
case SK_BindReference:
case SK_BindReferenceToTemporary:
case SK_ExtraneousCopyToTemporary:
case SK_UserConversion:
case SK_QualificationConversionLValue:
+ case SK_QualificationConversionXValue:
case SK_QualificationConversionRValue:
case SK_ConversionSequence:
case SK_ListInitialization:
case SK_CAssignment:
case SK_StringInit:
+ case SK_ObjCObjectConversion:
assert(Args.size() == 1);
- CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
+ CurInit = ExprResult(((Expr **)(Args.get()))[0]->Retain());
if (CurInit.isInvalid())
- return S.ExprError();
+ return ExprError();
break;
case SK_ConstructorInitialization:
@@ -3533,7 +3569,7 @@ InitializationSequence::Perform(Sema &S,
for (step_iterator Step = step_begin(), StepEnd = step_end();
Step != StepEnd; ++Step) {
if (CurInit.isInvalid())
- return S.ExprError();
+ return ExprError();
Expr *CurInitExpr = (Expr *)CurInit.get();
QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
@@ -3550,11 +3586,12 @@ InitializationSequence::Perform(Sema &S,
break;
case SK_CastDerivedToBaseRValue:
+ case SK_CastDerivedToBaseXValue:
case SK_CastDerivedToBaseLValue: {
// We have a derived-to-base cast that produces either an rvalue or an
// lvalue. Perform that cast.
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
// Casts to inaccessible base classes are allowed with C-style casts.
bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
@@ -3562,7 +3599,7 @@ InitializationSequence::Perform(Sema &S,
CurInitExpr->getLocStart(),
CurInitExpr->getSourceRange(),
&BasePath, IgnoreBaseAccess))
- return S.ExprError();
+ return ExprError();
if (S.BasePathInvolvesVirtualBase(BasePath)) {
QualType T = SourceType;
@@ -3573,11 +3610,17 @@ InitializationSequence::Perform(Sema &S,
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
- CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
- CastExpr::CK_DerivedToBase,
- (Expr*)CurInit.release(),
- BasePath,
- Step->Kind == SK_CastDerivedToBaseLValue));
+ ExprValueKind VK =
+ Step->Kind == SK_CastDerivedToBaseLValue ?
+ VK_LValue :
+ (Step->Kind == SK_CastDerivedToBaseXValue ?
+ VK_XValue :
+ VK_RValue);
+ CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+ Step->Type,
+ CK_DerivedToBase,
+ CurInit.get(),
+ &BasePath, VK));
break;
}
@@ -3589,7 +3632,7 @@ InitializationSequence::Perform(Sema &S,
<< BitField->getDeclName()
<< CurInitExpr->getSourceRange();
S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
- return S.ExprError();
+ return ExprError();
}
if (CurInitExpr->refersToVectorElement()) {
@@ -3598,14 +3641,14 @@ InitializationSequence::Perform(Sema &S,
<< Entity.getType().isVolatileQualified()
<< CurInitExpr->getSourceRange();
PrintInitLocationNote(S, Entity);
- return S.ExprError();
+ return ExprError();
}
// Reference binding does not have any corresponding ASTs.
// Check exception specifications
if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
- return S.ExprError();
+ return ExprError();
break;
@@ -3614,7 +3657,7 @@ InitializationSequence::Perform(Sema &S,
// Check exception specifications
if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
- return S.ExprError();
+ return ExprError();
break;
@@ -3626,7 +3669,7 @@ InitializationSequence::Perform(Sema &S,
case SK_UserConversion: {
// We have a user-defined conversion that invokes either a constructor
// or a conversion function.
- CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+ CastKind CastKind = CK_Unknown;
bool IsCopy = false;
FunctionDecl *Fn = Step->Function.Function;
DeclAccessPair FoundFn = Step->Function.FoundDecl;
@@ -3634,30 +3677,30 @@ InitializationSequence::Perform(Sema &S,
bool IsLvalue = false;
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
// Build a call to the selected constructor.
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+ ASTOwningVector<Expr*> ConstructorArgs(S);
SourceLocation Loc = CurInitExpr->getLocStart();
CurInit.release(); // Ownership transferred into MultiExprArg, below.
// Determine the arguments required to actually perform the constructor
// call.
if (S.CompleteConstructorCall(Constructor,
- Sema::MultiExprArg(S,
- (void **)&CurInitExpr,
- 1),
+ MultiExprArg(&CurInitExpr, 1),
Loc, ConstructorArgs))
- return S.ExprError();
+ return ExprError();
// Build the an expression that constructs a temporary.
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
if (CurInit.isInvalid())
- return S.ExprError();
+ return ExprError();
S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
FoundFn.getAccess());
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
- CastKind = CastExpr::CK_ConstructorConversion;
+ CastKind = CK_ConstructorConversion;
QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
S.IsDerivedFrom(SourceType, Class))
@@ -3677,7 +3720,7 @@ InitializationSequence::Perform(Sema &S,
// we don't want to turn off access control here for c-style casts.
if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
FoundFn, Conversion))
- return S.ExprError();
+ return ExprError();
// Do a little dance to make sure that CurInit has the proper
// pointer.
@@ -3687,9 +3730,9 @@ InitializationSequence::Perform(Sema &S,
CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn,
Conversion));
if (CurInit.isInvalid() || !CurInit.get())
- return S.ExprError();
+ return ExprError();
- CastKind = CastExpr::CK_UserDefinedConversion;
+ CastKind = CK_UserDefinedConversion;
CreatedObject = Conversion->getResultType()->isRecordType();
}
@@ -3711,35 +3754,41 @@ InitializationSequence::Perform(Sema &S,
}
CurInitExpr = CurInit.takeAs<Expr>();
- CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
- CastKind,
- CurInitExpr,
- CXXBaseSpecifierArray(),
- IsLvalue));
+ // FIXME: xvalues
+ CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+ CurInitExpr->getType(),
+ CastKind, CurInitExpr, 0,
+ IsLvalue ? VK_LValue : VK_RValue));
if (RequiresCopy)
CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
move(CurInit), /*IsExtraneousCopy=*/false);
-
+
break;
}
-
+
case SK_QualificationConversionLValue:
- case SK_QualificationConversionRValue:
+ case SK_QualificationConversionXValue:
+ case SK_QualificationConversionRValue: {
// Perform a qualification conversion; these can never go wrong.
- S.ImpCastExprToType(CurInitExpr, Step->Type,
- CastExpr::CK_NoOp,
- Step->Kind == SK_QualificationConversionLValue);
+ ExprValueKind VK =
+ Step->Kind == SK_QualificationConversionLValue ?
+ VK_LValue :
+ (Step->Kind == SK_QualificationConversionXValue ?
+ VK_XValue :
+ VK_RValue);
+ S.ImpCastExprToType(CurInitExpr, Step->Type, CK_NoOp, VK);
CurInit.release();
CurInit = S.Owned(CurInitExpr);
break;
-
+ }
+
case SK_ConversionSequence: {
bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS,
Sema::AA_Converting, IgnoreBaseAccess))
- return S.ExprError();
+ return ExprError();
CurInit.release();
CurInit = S.Owned(CurInitExpr);
@@ -3750,7 +3799,7 @@ InitializationSequence::Perform(Sema &S,
InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
QualType Ty = Step->Type;
if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty))
- return S.ExprError();
+ return ExprError();
CurInit.release();
CurInit = S.Owned(InitList);
@@ -3763,16 +3812,29 @@ InitializationSequence::Perform(Sema &S,
= cast<CXXConstructorDecl>(Step->Function.Function);
// Build a call to the selected constructor.
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
- SourceLocation Loc = Kind.getLocation();
-
+ ASTOwningVector<Expr*> ConstructorArgs(S);
+ SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid())
+ ? Kind.getEqualLoc()
+ : Kind.getLocation();
+
+ if (Kind.getKind() == InitializationKind::IK_Default) {
+ // Force even a trivial, implicit default constructor to be
+ // semantically checked. We do this explicitly because we don't build
+ // the definition for completely trivial constructors.
+ CXXRecordDecl *ClassDecl = Constructor->getParent();
+ assert(ClassDecl && "No parent class for constructor.");
+ if (Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
+ ClassDecl->hasTrivialConstructor() && !Constructor->isUsed(false))
+ S.DefineImplicitDefaultConstructor(Loc, Constructor);
+ }
+
// Determine the arguments required to actually perform the constructor
// call.
if (S.CompleteConstructorCall(Constructor, move(Args),
Loc, ConstructorArgs))
- return S.ExprError();
+ return ExprError();
- // Build the expression that constructs a temporary.
+
if (Entity.getKind() == InitializedEntity::EK_Temporary &&
NumArgs != 1 && // FIXME: Hack to work around cast weirdness
(Kind.getKind() == InitializationKind::IK_Direct ||
@@ -3780,11 +3842,11 @@ InitializationSequence::Perform(Sema &S,
// An explicitly-constructed temporary, e.g., X(1, 2).
unsigned NumExprs = ConstructorArgs.size();
Expr **Exprs = (Expr **)ConstructorArgs.take();
- S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
+ S.MarkDeclarationReferenced(Loc, Constructor);
CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
Constructor,
Entity.getType(),
- Kind.getLocation(),
+ Loc,
Exprs,
NumExprs,
Kind.getParenRange().getEnd(),
@@ -3815,7 +3877,7 @@ InitializationSequence::Perform(Sema &S,
ConstructKind);
}
if (CurInit.isInvalid())
- return S.ExprError();
+ return ExprError();
// Only check access if all of that succeeded.
S.CheckConstructorAccess(Loc, Constructor, Entity,
@@ -3867,7 +3929,7 @@ InitializationSequence::Perform(Sema &S,
getAssignmentAction(Entity),
&Complained)) {
PrintInitLocationNote(S, Entity);
- return S.ExprError();
+ return ExprError();
} else if (Complained)
PrintInitLocationNote(S, Entity);
@@ -3881,6 +3943,14 @@ InitializationSequence::Perform(Sema &S,
CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
break;
}
+
+ case SK_ObjCObjectConversion:
+ S.ImpCastExprToType(CurInitExpr, Step->Type,
+ CK_ObjCObjectLValueCast,
+ S.CastCategory(CurInitExpr));
+ CurInit.release();
+ CurInit = S.Owned(CurInitExpr);
+ break;
}
}
@@ -3937,16 +4007,14 @@ bool InitializationSequence::Diagnose(Sema &S,
<< DestType << Args[0]->getType()
<< Args[0]->getSourceRange();
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_No_Viable_Function:
S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Deleted: {
@@ -3954,9 +4022,8 @@ bool InitializationSequence::Diagnose(Sema &S,
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
- Kind.getLocation(),
- Best);
+ OverloadingResult Ovl
+ = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl == OR_Deleted) {
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
<< Best->Function->isDeleted();
@@ -4049,8 +4116,8 @@ bool InitializationSequence::Diagnose(Sema &S,
case OR_Ambiguous:
S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
<< DestType << ArgsRange;
- S.PrintOverloadCandidates(FailedCandidateSet,
- Sema::OCD_ViableCandidates, Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
+ Args, NumArgs);
break;
case OR_No_Viable_Function:
@@ -4095,17 +4162,15 @@ bool InitializationSequence::Diagnose(Sema &S,
S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
<< DestType << ArgsRange;
- S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
- Args, NumArgs);
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Deleted: {
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
<< true << DestType << ArgsRange;
OverloadCandidateSet::iterator Best;
- OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
- Kind.getLocation(),
- Best);
+ OverloadingResult Ovl
+ = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl == OR_Deleted) {
S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
<< Best->Function->isDeleted();
@@ -4288,6 +4353,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
break;
+ case SK_CastDerivedToBaseXValue:
+ OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
+ break;
+
case SK_CastDerivedToBaseLValue:
OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
break;
@@ -4307,10 +4376,13 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
case SK_UserConversion:
OS << "user-defined conversion via " << S->Function.Function;
break;
-
+
case SK_QualificationConversionRValue:
OS << "qualification conversion (rvalue)";
+ case SK_QualificationConversionXValue:
+ OS << "qualification conversion (xvalue)";
+
case SK_QualificationConversionLValue:
OS << "qualification conversion (lvalue)";
break;
@@ -4340,6 +4412,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
case SK_StringInit:
OS << "string initialization";
break;
+
+ case SK_ObjCObjectConversion:
+ OS << "Objective-C object conversion";
+ break;
}
}
}
@@ -4351,10 +4427,10 @@ void InitializationSequence::dump() const {
//===----------------------------------------------------------------------===//
// Initialization helper functions
//===----------------------------------------------------------------------===//
-Sema::OwningExprResult
+ExprResult
Sema::PerformCopyInitialization(const InitializedEntity &Entity,
SourceLocation EqualLoc,
- OwningExprResult Init) {
+ ExprResult Init) {
if (Init.isInvalid())
return ExprError();
@@ -4368,6 +4444,5 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
EqualLoc);
InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
Init.release();
- return Seq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&InitE, 1));
+ return Seq.Perform(*this, Entity, Kind, MultiExprArg(&InitE, 1));
}
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
deleted file mode 100644
index 44c36a735bc8..000000000000
--- a/lib/Sema/SemaInit.h
+++ /dev/null
@@ -1,765 +0,0 @@
-//===--- SemaInit.h - Semantic Analysis for Initializers --------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides supporting data types for initialization of objects.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_INIT_H
-#define LLVM_CLANG_SEMA_INIT_H
-
-#include "SemaOverload.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Parse/Action.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-
-namespace llvm {
- class raw_ostream;
-}
-
-namespace clang {
-
-class CXXBaseSpecifier;
-class DeclaratorDecl;
-class DeclaratorInfo;
-class FieldDecl;
-class FunctionDecl;
-class ParmVarDecl;
-class Sema;
-class TypeLoc;
-class VarDecl;
-
-/// \brief Describes an entity that is being initialized.
-class InitializedEntity {
-public:
- /// \brief Specifies the kind of entity being initialized.
- enum EntityKind {
- /// \brief The entity being initialized is a variable.
- EK_Variable,
- /// \brief The entity being initialized is a function parameter.
- EK_Parameter,
- /// \brief The entity being initialized is the result of a function call.
- EK_Result,
- /// \brief The entity being initialized is an exception object that
- /// is being thrown.
- EK_Exception,
- /// \brief The entity being initialized is a non-static data member
- /// subobject.
- EK_Member,
- /// \brief The entity being initialized is an element of an array.
- EK_ArrayElement,
- /// \brief The entity being initialized is an object (or array of
- /// objects) allocated via new.
- EK_New,
- /// \brief The entity being initialized is a temporary object.
- EK_Temporary,
- /// \brief The entity being initialized is a base member subobject.
- EK_Base,
- /// \brief The entity being initialized is an element of a vector.
- /// or vector.
- EK_VectorElement,
- /// \brief The entity being initialized is a field of block descriptor for
- /// the copied-in c++ object.
- EK_BlockElement
- };
-
-private:
- /// \brief The kind of entity being initialized.
- EntityKind Kind;
-
- /// \brief If non-NULL, the parent entity in which this
- /// initialization occurs.
- const InitializedEntity *Parent;
-
- /// \brief The type of the object or reference being initialized.
- QualType Type;
-
- union {
- /// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member,
- /// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
- DeclaratorDecl *VariableOrMember;
-
- struct {
- /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
- /// location of the 'return', 'throw', or 'new' keyword,
- /// respectively. When Kind == EK_Temporary, the location where
- /// the temporary is being created.
- unsigned Location;
-
- /// \brief Whether the
- bool NRVO;
- } LocAndNRVO;
-
- /// \brief When Kind == EK_Base, the base specifier that provides the
- /// base class. The lower bit specifies whether the base is an inherited
- /// virtual base.
- uintptr_t Base;
-
- /// \brief When Kind == EK_ArrayElement or EK_VectorElement, the
- /// index of the array or vector element being initialized.
- unsigned Index;
- };
-
- InitializedEntity() { }
-
- /// \brief Create the initialization entity for a variable.
- InitializedEntity(VarDecl *Var)
- : Kind(EK_Variable), Parent(0), Type(Var->getType()),
- VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) { }
-
- /// \brief Create the initialization entity for a parameter.
- InitializedEntity(ParmVarDecl *Parm)
- : Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()),
- VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) { }
-
- /// \brief Create the initialization entity for the result of a
- /// function, throwing an object, performing an explicit cast, or
- /// initializing a parameter for which there is no declaration.
- InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
- bool NRVO = false)
- : Kind(Kind), Parent(0), Type(Type)
- {
- LocAndNRVO.Location = Loc.getRawEncoding();
- LocAndNRVO.NRVO = NRVO;
- }
-
- /// \brief Create the initialization entity for a member subobject.
- InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
- : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
- VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member)) { }
-
- /// \brief Create the initialization entity for an array element.
- InitializedEntity(ASTContext &Context, unsigned Index,
- const InitializedEntity &Parent);
-
-public:
- /// \brief Create the initialization entity for a variable.
- static InitializedEntity InitializeVariable(VarDecl *Var) {
- return InitializedEntity(Var);
- }
-
- /// \brief Create the initialization entity for a parameter.
- static InitializedEntity InitializeParameter(ParmVarDecl *Parm) {
- return InitializedEntity(Parm);
- }
-
- /// \brief Create the initialization entity for a parameter that is
- /// only known by its type.
- static InitializedEntity InitializeParameter(QualType Type) {
- InitializedEntity Entity;
- Entity.Kind = EK_Parameter;
- Entity.Type = Type;
- Entity.Parent = 0;
- Entity.VariableOrMember = 0;
- return Entity;
- }
-
- /// \brief Create the initialization entity for the result of a function.
- static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
- QualType Type, bool NRVO) {
- return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
- }
-
- static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
- QualType Type, bool NRVO) {
- return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
- }
-
- /// \brief Create the initialization entity for an exception object.
- static InitializedEntity InitializeException(SourceLocation ThrowLoc,
- QualType Type, bool NRVO) {
- return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
- }
-
- /// \brief Create the initialization entity for an object allocated via new.
- static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
- return InitializedEntity(EK_New, NewLoc, Type);
- }
-
- /// \brief Create the initialization entity for a temporary.
- static InitializedEntity InitializeTemporary(QualType Type) {
- return InitializedEntity(EK_Temporary, SourceLocation(), Type);
- }
-
- /// \brief Create the initialization entity for a base class subobject.
- static InitializedEntity InitializeBase(ASTContext &Context,
- CXXBaseSpecifier *Base,
- bool IsInheritedVirtualBase);
-
- /// \brief Create the initialization entity for a member subobject.
- static InitializedEntity InitializeMember(FieldDecl *Member,
- const InitializedEntity *Parent = 0) {
- return InitializedEntity(Member, Parent);
- }
-
- /// \brief Create the initialization entity for an array element.
- static InitializedEntity InitializeElement(ASTContext &Context,
- unsigned Index,
- const InitializedEntity &Parent) {
- return InitializedEntity(Context, Index, Parent);
- }
-
- /// \brief Determine the kind of initialization.
- EntityKind getKind() const { return Kind; }
-
- /// \brief Retrieve the parent of the entity being initialized, when
- /// the initialization itself is occuring within the context of a
- /// larger initialization.
- const InitializedEntity *getParent() const { return Parent; }
-
- /// \brief Retrieve type being initialized.
- QualType getType() const { return Type; }
-
- /// \brief Retrieve the name of the entity being initialized.
- DeclarationName getName() const;
-
- /// \brief Retrieve the variable, parameter, or field being
- /// initialized.
- DeclaratorDecl *getDecl() const;
-
- /// \brief Determine whether this initialization allows the named return
- /// value optimization, which also applies to thrown objects.
- bool allowsNRVO() const;
-
- /// \brief Retrieve the base specifier.
- CXXBaseSpecifier *getBaseSpecifier() const {
- assert(getKind() == EK_Base && "Not a base specifier");
- return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1);
- }
-
- /// \brief Return whether the base is an inherited virtual base.
- bool isInheritedVirtualBase() const {
- assert(getKind() == EK_Base && "Not a base specifier");
- return Base & 0x1;
- }
-
- /// \brief Determine the location of the 'return' keyword when initializing
- /// the result of a function call.
- SourceLocation getReturnLoc() const {
- assert(getKind() == EK_Result && "No 'return' location!");
- return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
- }
-
- /// \brief Determine the location of the 'throw' keyword when initializing
- /// an exception object.
- SourceLocation getThrowLoc() const {
- assert(getKind() == EK_Exception && "No 'throw' location!");
- return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
- }
-
- /// \brief If this is already the initializer for an array or vector
- /// element, sets the element index.
- void setElementIndex(unsigned Index) {
- assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement);
- this->Index = Index;
- }
-};
-
-/// \brief Describes the kind of initialization being performed, along with
-/// location information for tokens related to the initialization (equal sign,
-/// parentheses).
-class InitializationKind {
-public:
- /// \brief The kind of initialization being performed.
- enum InitKind {
- IK_Direct, ///< Direct initialization
- IK_Copy, ///< Copy initialization
- IK_Default, ///< Default initialization
- IK_Value ///< Value initialization
- };
-
-private:
- /// \brief The kind of initialization that we're storing.
- enum StoredInitKind {
- SIK_Direct = IK_Direct, ///< Direct initialization
- SIK_Copy = IK_Copy, ///< Copy initialization
- SIK_Default = IK_Default, ///< Default initialization
- SIK_Value = IK_Value, ///< Value initialization
- SIK_ImplicitValue, ///< Implicit value initialization
- SIK_DirectCast, ///< Direct initialization due to a cast
- /// \brief Direct initialization due to a C-style or functional cast.
- SIK_DirectCStyleOrFunctionalCast
- };
-
- /// \brief The kind of initialization being performed.
- StoredInitKind Kind;
-
- /// \brief The source locations involved in the initialization.
- SourceLocation Locations[3];
-
- InitializationKind(StoredInitKind Kind, SourceLocation Loc1,
- SourceLocation Loc2, SourceLocation Loc3)
- : Kind(Kind)
- {
- Locations[0] = Loc1;
- Locations[1] = Loc2;
- Locations[2] = Loc3;
- }
-
-public:
- /// \brief Create a direct initialization.
- static InitializationKind CreateDirect(SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
- }
-
- /// \brief Create a direct initialization due to a cast.
- static InitializationKind CreateCast(SourceRange TypeRange,
- bool IsCStyleCast) {
- return InitializationKind(IsCStyleCast? SIK_DirectCStyleOrFunctionalCast
- : SIK_DirectCast,
- TypeRange.getBegin(), TypeRange.getBegin(),
- TypeRange.getEnd());
- }
-
- /// \brief Create a copy initialization.
- static InitializationKind CreateCopy(SourceLocation InitLoc,
- SourceLocation EqualLoc) {
- return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
- }
-
- /// \brief Create a default initialization.
- static InitializationKind CreateDefault(SourceLocation InitLoc) {
- return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
- }
-
- /// \brief Create a value initialization.
- static InitializationKind CreateValue(SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc,
- bool isImplicit = false) {
- return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value,
- InitLoc, LParenLoc, RParenLoc);
- }
-
- /// \brief Determine the initialization kind.
- InitKind getKind() const {
- if (Kind > SIK_ImplicitValue)
- return IK_Direct;
- if (Kind == SIK_ImplicitValue)
- return IK_Value;
-
- return (InitKind)Kind;
- }
-
- /// \brief Determine whether this initialization is an explicit cast.
- bool isExplicitCast() const {
- return Kind == SIK_DirectCast || Kind == SIK_DirectCStyleOrFunctionalCast;
- }
-
- /// \brief Determine whether this initialization is a C-style cast.
- bool isCStyleOrFunctionalCast() const {
- return Kind == SIK_DirectCStyleOrFunctionalCast;
- }
-
- /// \brief Determine whether this initialization is an implicit
- /// value-initialization, e.g., as occurs during aggregate
- /// initialization.
- bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
-
- /// \brief Retrieve the location at which initialization is occurring.
- SourceLocation getLocation() const { return Locations[0]; }
-
- /// \brief Retrieve the source range that covers the initialization.
- SourceRange getRange() const {
- return SourceRange(Locations[0], Locations[2]);
- }
-
- /// \brief Retrieve the location of the equal sign for copy initialization
- /// (if present).
- SourceLocation getEqualLoc() const {
- assert(Kind == SIK_Copy && "Only copy initialization has an '='");
- return Locations[1];
- }
-
- /// \brief Retrieve the source range containing the locations of the open
- /// and closing parentheses for value and direct initializations.
- SourceRange getParenRange() const {
- assert((getKind() == IK_Direct || Kind == SIK_Value) &&
- "Only direct- and value-initialization have parentheses");
- return SourceRange(Locations[1], Locations[2]);
- }
-};
-
-/// \brief Describes the sequence of initializations required to initialize
-/// a given object or reference with a set of arguments.
-class InitializationSequence {
-public:
- /// \brief Describes the kind of initialization sequence computed.
- ///
- /// FIXME: Much of this information is in the initialization steps... why is
- /// it duplicated here?
- enum SequenceKind {
- /// \brief A failed initialization sequence. The failure kind tells what
- /// happened.
- FailedSequence = 0,
-
- /// \brief A dependent initialization, which could not be
- /// type-checked due to the presence of dependent types or
- /// dependently-type expressions.
- DependentSequence,
-
- /// \brief A user-defined conversion sequence.
- UserDefinedConversion,
-
- /// \brief A constructor call.
- ConstructorInitialization,
-
- /// \brief A reference binding.
- ReferenceBinding,
-
- /// \brief List initialization
- ListInitialization,
-
- /// \brief Zero-initialization.
- ZeroInitialization,
-
- /// \brief No initialization required.
- NoInitialization,
-
- /// \brief Standard conversion sequence.
- StandardConversion,
-
- /// \brief C conversion sequence.
- CAssignment,
-
- /// \brief String initialization
- StringInit
- };
-
- /// \brief Describes the kind of a particular step in an initialization
- /// sequence.
- enum StepKind {
- /// \brief Resolve the address of an overloaded function to a specific
- /// function declaration.
- SK_ResolveAddressOfOverloadedFunction,
- /// \brief Perform a derived-to-base cast, producing an rvalue.
- SK_CastDerivedToBaseRValue,
- /// \brief Perform a derived-to-base cast, producing an lvalue.
- SK_CastDerivedToBaseLValue,
- /// \brief Reference binding to an lvalue.
- SK_BindReference,
- /// \brief Reference binding to a temporary.
- SK_BindReferenceToTemporary,
- /// \brief An optional copy of a temporary object to another
- /// temporary object, which is permitted (but not required) by
- /// C++98/03 but not C++0x.
- SK_ExtraneousCopyToTemporary,
- /// \brief Perform a user-defined conversion, either via a conversion
- /// function or via a constructor.
- SK_UserConversion,
- /// \brief Perform a qualification conversion, producing an rvalue.
- SK_QualificationConversionRValue,
- /// \brief Perform a qualification conversion, producing an lvalue.
- SK_QualificationConversionLValue,
- /// \brief Perform an implicit conversion sequence.
- SK_ConversionSequence,
- /// \brief Perform list-initialization
- SK_ListInitialization,
- /// \brief Perform initialization via a constructor.
- SK_ConstructorInitialization,
- /// \brief Zero-initialize the object
- SK_ZeroInitialization,
- /// \brief C assignment
- SK_CAssignment,
- /// \brief Initialization by string
- SK_StringInit
- };
-
- /// \brief A single step in the initialization sequence.
- class Step {
- public:
- /// \brief The kind of conversion or initialization step we are taking.
- StepKind Kind;
-
- // \brief The type that results from this initialization.
- QualType Type;
-
- union {
- /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
- /// SK_UserConversion, the function that the expression should be
- /// resolved to or the conversion function to call, respectively.
- ///
- /// Always a FunctionDecl.
- /// For conversion decls, the naming class is the source type.
- /// For construct decls, the naming class is the target type.
- struct {
- FunctionDecl *Function;
- DeclAccessPair FoundDecl;
- } Function;
-
- /// \brief When Kind = SK_ConversionSequence, the implicit conversion
- /// sequence
- ImplicitConversionSequence *ICS;
- };
-
- void Destroy();
- };
-
-private:
- /// \brief The kind of initialization sequence computed.
- enum SequenceKind SequenceKind;
-
- /// \brief Steps taken by this initialization.
- llvm::SmallVector<Step, 4> Steps;
-
-public:
- /// \brief Describes why initialization failed.
- enum FailureKind {
- /// \brief Too many initializers provided for a reference.
- FK_TooManyInitsForReference,
- /// \brief Array must be initialized with an initializer list.
- FK_ArrayNeedsInitList,
- /// \brief Array must be initialized with an initializer list or a
- /// string literal.
- FK_ArrayNeedsInitListOrStringLiteral,
- /// \brief Cannot resolve the address of an overloaded function.
- FK_AddressOfOverloadFailed,
- /// \brief Overloading due to reference initialization failed.
- FK_ReferenceInitOverloadFailed,
- /// \brief Non-const lvalue reference binding to a temporary.
- FK_NonConstLValueReferenceBindingToTemporary,
- /// \brief Non-const lvalue reference binding to an lvalue of unrelated
- /// type.
- FK_NonConstLValueReferenceBindingToUnrelated,
- /// \brief Rvalue reference binding to an lvalue.
- FK_RValueReferenceBindingToLValue,
- /// \brief Reference binding drops qualifiers.
- FK_ReferenceInitDropsQualifiers,
- /// \brief Reference binding failed.
- FK_ReferenceInitFailed,
- /// \brief Implicit conversion failed.
- FK_ConversionFailed,
- /// \brief Too many initializers for scalar
- FK_TooManyInitsForScalar,
- /// \brief Reference initialization from an initializer list
- FK_ReferenceBindingToInitList,
- /// \brief Initialization of some unused destination type with an
- /// initializer list.
- FK_InitListBadDestinationType,
- /// \brief Overloading for a user-defined conversion failed.
- FK_UserConversionOverloadFailed,
- /// \brief Overloaded for initialization by constructor failed.
- FK_ConstructorOverloadFailed,
- /// \brief Default-initialization of a 'const' object.
- FK_DefaultInitOfConst,
- /// \brief Initialization of an incomplete type.
- FK_Incomplete
- };
-
-private:
- /// \brief The reason why initialization failued.
- FailureKind Failure;
-
- /// \brief The failed result of overload resolution.
- OverloadingResult FailedOverloadResult;
-
- /// \brief The candidate set created when initialization failed.
- OverloadCandidateSet FailedCandidateSet;
-
- /// \brief Prints a follow-up note that highlights the location of
- /// the initialized entity, if it's remote.
- void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
-
-public:
- /// \brief Try to perform initialization of the given entity, creating a
- /// record of the steps required to perform the initialization.
- ///
- /// The generated initialization sequence will either contain enough
- /// information to diagnose
- ///
- /// \param S the semantic analysis object.
- ///
- /// \param Entity the entity being initialized.
- ///
- /// \param Kind the kind of initialization being performed.
- ///
- /// \param Args the argument(s) provided for initialization.
- ///
- /// \param NumArgs the number of arguments provided for initialization.
- InitializationSequence(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr **Args,
- unsigned NumArgs);
-
- ~InitializationSequence();
-
- /// \brief Perform the actual initialization of the given entity based on
- /// the computed initialization sequence.
- ///
- /// \param S the semantic analysis object.
- ///
- /// \param Entity the entity being initialized.
- ///
- /// \param Kind the kind of initialization being performed.
- ///
- /// \param Args the argument(s) provided for initialization, ownership of
- /// which is transfered into the routine.
- ///
- /// \param ResultType if non-NULL, will be set to the type of the
- /// initialized object, which is the type of the declaration in most
- /// cases. However, when the initialized object is a variable of
- /// incomplete array type and the initializer is an initializer
- /// list, this type will be set to the completed array type.
- ///
- /// \returns an expression that performs the actual object initialization, if
- /// the initialization is well-formed. Otherwise, emits diagnostics
- /// and returns an invalid expression.
- Action::OwningExprResult Perform(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Action::MultiExprArg Args,
- QualType *ResultType = 0);
-
- /// \brief Diagnose an potentially-invalid initialization sequence.
- ///
- /// \returns true if the initialization sequence was ill-formed,
- /// false otherwise.
- bool Diagnose(Sema &S,
- const InitializedEntity &Entity,
- const InitializationKind &Kind,
- Expr **Args, unsigned NumArgs);
-
- /// \brief Determine the kind of initialization sequence computed.
- enum SequenceKind getKind() const { return SequenceKind; }
-
- /// \brief Set the kind of sequence computed.
- void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
-
- /// \brief Determine whether the initialization sequence is valid.
- operator bool() const { return SequenceKind != FailedSequence; }
-
- typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator;
- step_iterator step_begin() const { return Steps.begin(); }
- step_iterator step_end() const { return Steps.end(); }
-
- /// \brief Determine whether this initialization is a direct reference
- /// binding (C++ [dcl.init.ref]).
- bool isDirectReferenceBinding() const;
-
- /// \brief Determine whether this initialization failed due to an ambiguity.
- bool isAmbiguous() const;
-
- /// \brief Determine whether this initialization is direct call to a
- /// constructor.
- bool isConstructorInitialization() const;
-
- /// \brief Add a new step in the initialization that resolves the address
- /// of an overloaded function to a specific function declaration.
- ///
- /// \param Function the function to which the overloaded function reference
- /// resolves.
- void AddAddressOverloadResolutionStep(FunctionDecl *Function,
- DeclAccessPair Found);
-
- /// \brief Add a new step in the initialization that performs a derived-to-
- /// base cast.
- ///
- /// \param BaseType the base type to which we will be casting.
- ///
- /// \param IsLValue true if the result of this cast will be treated as
- /// an lvalue.
- void AddDerivedToBaseCastStep(QualType BaseType, bool IsLValue);
-
- /// \brief Add a new step binding a reference to an object.
- ///
- /// \param BindingTemporary True if we are binding a reference to a temporary
- /// object (thereby extending its lifetime); false if we are binding to an
- /// lvalue or an lvalue treated as an rvalue.
- ///
- /// \param UnnecessaryCopy True if we should check for a copy
- /// constructor for a completely unnecessary but
- void AddReferenceBindingStep(QualType T, bool BindingTemporary);
-
- /// \brief Add a new step that makes an extraneous copy of the input
- /// to a temporary of the same class type.
- ///
- /// This extraneous copy only occurs during reference binding in
- /// C++98/03, where we are permitted (but not required) to introduce
- /// an extra copy. At a bare minimum, we must check that we could
- /// call the copy constructor, and produce a diagnostic if the copy
- /// constructor is inaccessible or no copy constructor matches.
- //
- /// \param T The type of the temporary being created.
- void AddExtraneousCopyToTemporary(QualType T);
-
- /// \brief Add a new step invoking a conversion function, which is either
- /// a constructor or a conversion function.
- void AddUserConversionStep(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
- QualType T);
-
- /// \brief Add a new step that performs a qualification conversion to the
- /// given type.
- void AddQualificationConversionStep(QualType Ty, bool IsLValue);
-
- /// \brief Add a new step that applies an implicit conversion sequence.
- void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
- QualType T);
-
- /// \brief Add a list-initialiation step
- void AddListInitializationStep(QualType T);
-
- /// \brief Add a constructor-initialization step.
- void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
- AccessSpecifier Access,
- QualType T);
-
- /// \brief Add a zero-initialization step.
- void AddZeroInitializationStep(QualType T);
-
- /// \brief Add a C assignment step.
- //
- // FIXME: It isn't clear whether this should ever be needed;
- // ideally, we would handle everything needed in C in the common
- // path. However, that isn't the case yet.
- void AddCAssignmentStep(QualType T);
-
- /// \brief Add a string init step.
- void AddStringInitStep(QualType T);
-
- /// \brief Note that this initialization sequence failed.
- void SetFailed(FailureKind Failure) {
- SequenceKind = FailedSequence;
- this->Failure = Failure;
- }
-
- /// \brief Note that this initialization sequence failed due to failed
- /// overload resolution.
- void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
-
- /// \brief Retrieve a reference to the candidate set when overload
- /// resolution fails.
- OverloadCandidateSet &getFailedCandidateSet() {
- return FailedCandidateSet;
- }
-
- /// \brief Determine why initialization failed.
- FailureKind getFailureKind() const {
- assert(getKind() == FailedSequence && "Not an initialization failure!");
- return Failure;
- }
-
- /// \brief Dump a representation of this initialization sequence to
- /// the given stream, for debugging purposes.
- void dump(llvm::raw_ostream &OS) const;
-
- /// \brief Dump a representation of this initialization sequence to
- /// standard error, for debugging purposes.
- void dump() const;
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_INIT_H
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 2e651838df95..306e95a497e8 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -11,8 +11,13 @@
// Objective-C++.
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
@@ -21,9 +26,9 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
@@ -35,6 +40,7 @@
#include <algorithm>
using namespace clang;
+using namespace sema;
namespace {
class UnqualUsingEntry {
@@ -100,7 +106,7 @@ namespace {
End = S->using_directives_end();
for (; I != End; ++I)
- visit(I->getAs<UsingDirectiveDecl>(), InnermostFileDC);
+ visit(*I, InnermostFileDC);
}
}
}
@@ -254,6 +260,12 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
case Sema::LookupObjCProtocolName:
IDNS = Decl::IDNS_ObjCProtocol;
break;
+
+ case Sema::LookupAnyName:
+ IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member
+ | Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
+ | Decl::IDNS_Type;
+ break;
}
return IDNS;
}
@@ -267,7 +279,7 @@ void LookupResult::configure() {
// operators, make sure that the implicitly-declared new and delete
// operators can be found.
if (!isForRedeclaration()) {
- switch (Name.getCXXOverloadedOperator()) {
+ switch (NameInfo.getName().getCXXOverloadedOperator()) {
case OO_New:
case OO_Delete:
case OO_Array_New:
@@ -281,6 +293,22 @@ void LookupResult::configure() {
}
}
+#ifndef NDEBUG
+void LookupResult::sanity() const {
+ assert(ResultKind != NotFound || Decls.size() == 0);
+ assert(ResultKind != Found || Decls.size() == 1);
+ assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
+ (Decls.size() == 1 &&
+ isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
+ assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
+ assert(ResultKind != Ambiguous || Decls.size() > 1 ||
+ (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
+ assert((Paths != NULL) == (ResultKind == Ambiguous &&
+ (Ambiguity == AmbiguousBaseSubobjectTypes ||
+ Ambiguity == AmbiguousBaseSubobjects)));
+}
+#endif
+
// Necessary because CXXBasePaths is not complete in Sema.h
void LookupResult::deletePaths(CXXBasePaths *Paths) {
delete Paths;
@@ -311,7 +339,8 @@ void LookupResult::resolveKind() {
if (ResultKind == Ambiguous) return;
llvm::SmallPtrSet<NamedDecl*, 16> Unique;
-
+ llvm::SmallPtrSet<QualType, 16> UniqueTypes;
+
bool Ambiguous = false;
bool HasTag = false, HasFunction = false, HasNonFunction = false;
bool HasFunctionTemplate = false, HasUnresolved = false;
@@ -323,32 +352,49 @@ void LookupResult::resolveKind() {
NamedDecl *D = Decls[I]->getUnderlyingDecl();
D = cast<NamedDecl>(D->getCanonicalDecl());
+ // Redeclarations of types via typedef can occur both within a scope
+ // and, through using declarations and directives, across scopes. There is
+ // no ambiguity if they all refer to the same type, so unique based on the
+ // canonical type.
+ if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+ if (!TD->getDeclContext()->isRecord()) {
+ QualType T = SemaRef.Context.getTypeDeclType(TD);
+ if (!UniqueTypes.insert(SemaRef.Context.getCanonicalType(T))) {
+ // The type is not unique; pull something off the back and continue
+ // at this index.
+ Decls[I] = Decls[--N];
+ continue;
+ }
+ }
+ }
+
if (!Unique.insert(D)) {
// If it's not unique, pull something off the back (and
// continue at this index).
Decls[I] = Decls[--N];
+ continue;
+ }
+
+ // Otherwise, do some decl type analysis and then continue.
+
+ if (isa<UnresolvedUsingValueDecl>(D)) {
+ HasUnresolved = true;
+ } else if (isa<TagDecl>(D)) {
+ if (HasTag)
+ Ambiguous = true;
+ UniqueTagIndex = I;
+ HasTag = true;
+ } else if (isa<FunctionTemplateDecl>(D)) {
+ HasFunction = true;
+ HasFunctionTemplate = true;
+ } else if (isa<FunctionDecl>(D)) {
+ HasFunction = true;
} else {
- // Otherwise, do some decl type analysis and then continue.
-
- if (isa<UnresolvedUsingValueDecl>(D)) {
- HasUnresolved = true;
- } else if (isa<TagDecl>(D)) {
- if (HasTag)
- Ambiguous = true;
- UniqueTagIndex = I;
- HasTag = true;
- } else if (isa<FunctionTemplateDecl>(D)) {
- HasFunction = true;
- HasFunctionTemplate = true;
- } else if (isa<FunctionDecl>(D)) {
- HasFunction = true;
- } else {
- if (HasNonFunction)
- Ambiguous = true;
- HasNonFunction = true;
- }
- I++;
+ if (HasNonFunction)
+ Ambiguous = true;
+ HasNonFunction = true;
}
+ I++;
}
// C++ [basic.scope.hiding]p2:
@@ -451,6 +497,10 @@ static bool LookupBuiltin(Sema &S, LookupResult &R) {
/// the class at this point.
static bool CanDeclareSpecialMemberFunction(ASTContext &Context,
const CXXRecordDecl *Class) {
+ // Don't do it if the class is invalid.
+ if (Class->isInvalidDecl())
+ return false;
+
// We need to have a definition for the class.
if (!Class->getDefinition() || Class->isDependentContext())
return false;
@@ -608,7 +658,7 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {
// result), perform template argument deduction and place the
// specialization into the result set. We do this to avoid forcing all
// callers to perform special deduction for conversion functions.
- Sema::TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
+ TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
FunctionDecl *Specialization = 0;
const FunctionProtoType *ConvProto
@@ -783,7 +833,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// Check whether the IdResolver has anything in this scope.
bool Found = false;
- for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+ for (; I != IEnd && S->isDeclScope(*I); ++I) {
if (R.isAcceptableDecl(*I)) {
Found = true;
R.addDecl(*I);
@@ -881,7 +931,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
for (; S; S = S->getParent()) {
// Check whether the IdResolver has anything in this scope.
bool Found = false;
- for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+ for (; I != IEnd && S->isDeclScope(*I); ++I) {
if (R.isAcceptableDecl(*I)) {
// We found something. Look for anything else in our scope
// with this same name and in an acceptable identifier
@@ -1017,7 +1067,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
if (NameKind == LookupRedeclarationWithLinkage) {
// Determine whether this (or a previous) declaration is
// out-of-scope.
- if (!LeftStartingScope && !S->isDeclScope(DeclPtrTy::make(*I)))
+ if (!LeftStartingScope && !S->isDeclScope(*I))
LeftStartingScope = true;
// If we found something outside of our starting scope that
@@ -1034,14 +1084,14 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
// Figure out what scope the identifier is in.
while (!(S->getFlags() & Scope::DeclScope) ||
- !S->isDeclScope(DeclPtrTy::make(*I)))
+ !S->isDeclScope(*I))
S = S->getParent();
// Find the last declaration in this scope (with the same
// name, naturally).
IdentifierResolver::iterator LastI = I;
for (++LastI; LastI != IEnd; ++LastI) {
- if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
+ if (!S->isDeclScope(*LastI))
break;
R.addDecl(*LastI);
}
@@ -1177,6 +1227,17 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,
return Found;
}
+/// \brief Callback that looks for any member of a class with the given name.
+static bool LookupAnyMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ void *Name) {
+ RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+
+ DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+ Path.Decls = BaseRecord->lookup(N);
+ return Path.Decls.first != Path.Decls.second;
+}
+
/// \brief Perform qualified name lookup into a given context.
///
/// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
@@ -1272,6 +1333,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
BaseCallback = &CXXRecordDecl::FindTagMember;
break;
+ case LookupAnyName:
+ BaseCallback = &LookupAnyMember;
+ break;
+
case LookupUsingDeclName:
// This lookup is for redeclarations only.
@@ -1554,7 +1619,11 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
// We don't use DeclContext::getEnclosingNamespaceContext() as this may
// be a locally scoped record.
- while (Ctx->isRecord() || Ctx->isTransparentContext())
+ // We skip out of inline namespaces. The innermost non-inline namespace
+ // contains all names of all its nested inline namespaces anyway, so we can
+ // replace the entire inline namespace tree with its root.
+ while (Ctx->isRecord() || Ctx->isTransparentContext() ||
+ Ctx->isInlineNamespace())
Ctx = Ctx->getParent();
if (Ctx->isFileContext())
@@ -1894,7 +1963,7 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
// parameter types and return type.
Arg = Arg->IgnoreParens();
if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
- if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+ if (unaryOp->getOpcode() == UO_AddrOf)
Arg = unaryOp->getSubExpr();
UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
@@ -2201,6 +2270,10 @@ public:
return !VisitedContexts.insert(Ctx);
}
+ bool alreadyVisitedContext(DeclContext *Ctx) {
+ return VisitedContexts.count(Ctx);
+ }
+
/// \brief Determine whether the given declaration is hidden in the
/// current scope.
///
@@ -2354,9 +2427,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
Visited.add(ND);
}
- // Visit transparent contexts inside this context.
+ // Visit transparent contexts and inline namespaces inside this context.
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
- if (InnerCtx->isTransparentContext())
+ if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
Consumer, Visited);
}
@@ -2429,8 +2502,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
}
// Traverse protocols.
- for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
- E = IFace->protocol_end(); I != E; ++I) {
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ I = IFace->all_referenced_protocol_begin(),
+ E = IFace->all_referenced_protocol_end(); I != E; ++I) {
ShadowContextRAII Shadow(Visited);
LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
Visited);
@@ -2481,12 +2555,14 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,
if (!S)
return;
- if (!S->getEntity() || !S->getParent() ||
+ if (!S->getEntity() ||
+ (!S->getParent() &&
+ !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
// Walk through the declarations in this Scope.
for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
D != DEnd; ++D) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
if (Result.isAcceptableDecl(ND)) {
Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
Visited.add(ND);
@@ -2559,7 +2635,8 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,
}
void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer) {
+ VisibleDeclConsumer &Consumer,
+ bool IncludeGlobalScope) {
// Determine the set of using directives available during
// unqualified name lookup.
Scope *Initial = S;
@@ -2576,14 +2653,19 @@ void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
// Look for visible declarations.
LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
VisibleDeclsRecord Visited;
+ if (!IncludeGlobalScope)
+ Visited.visitedContext(Context.getTranslationUnitDecl());
ShadowContextRAII Shadow(Visited);
::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited);
}
void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
- VisibleDeclConsumer &Consumer) {
+ VisibleDeclConsumer &Consumer,
+ bool IncludeGlobalScope) {
LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
VisibleDeclsRecord Visited;
+ if (!IncludeGlobalScope)
+ Visited.visitedContext(Context.getTranslationUnitDecl());
ShadowContextRAII Shadow(Visited);
::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
/*InBaseClass=*/false, Consumer, Visited);
@@ -2911,7 +2993,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
if (S && S->getContinueParent())
Consumer.addKeywordResult(Context, "continue");
- if (!getSwitchStack().empty()) {
+ if (!getCurFunction()->SwitchStack.empty()) {
Consumer.addKeywordResult(Context, "case");
Consumer.addKeywordResult(Context, "default");
}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index ff60599b8510..7181d58f7fb0 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -12,9 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
+#include "llvm/ADT/DenseSet.h"
using namespace clang;
@@ -22,14 +24,14 @@ using namespace clang;
// Grammar actions.
//===----------------------------------------------------------------------===//
-Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD,
- ObjCDeclSpec &ODS,
- Selector GetterSel,
- Selector SetterSel,
- DeclPtrTy ClassCategory,
- bool *isOverridingProperty,
- tok::ObjCKeywordKind MethodImplKind) {
+Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
+ FieldDeclarator &FD,
+ ObjCDeclSpec &ODS,
+ Selector GetterSel,
+ Selector SetterSel,
+ Decl *ClassCategory,
+ bool *isOverridingProperty,
+ tok::ObjCKeywordKind MethodImplKind) {
unsigned Attributes = ODS.getPropertyAttributes();
bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
// default is readwrite!
@@ -45,15 +47,15 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
QualType T = TSI->getType();
if (T->isReferenceType()) {
Diag(AtLoc, diag::error_reference_property);
- return DeclPtrTy();
+ return 0;
}
// Proceed with constructing the ObjCPropertDecls.
ObjCContainerDecl *ClassDecl =
- cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());
+ cast<ObjCContainerDecl>(ClassCategory);
if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
if (CDecl->IsClassExtension()) {
- DeclPtrTy Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
+ Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
FD, GetterSel, SetterSel,
isAssign, isReadWrite,
Attributes,
@@ -64,16 +66,16 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
return Res;
}
- DeclPtrTy Res = DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
- GetterSel, SetterSel,
- isAssign, isReadWrite,
- Attributes, TSI, MethodImplKind));
+ Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
+ GetterSel, SetterSel,
+ isAssign, isReadWrite,
+ Attributes, TSI, MethodImplKind);
// Validate the attributes on the @property.
CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
return Res;
}
-Sema::DeclPtrTy
+Decl *
Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
SourceLocation AtLoc, FieldDeclarator &FD,
Selector GetterSel, Selector SetterSel,
@@ -92,7 +94,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
Diag(AtLoc, diag::err_duplicate_property);
Diag(prevDecl->getLocation(), diag::note_property_declare);
- return DeclPtrTy();
+ return 0;
}
// Create a new ObjCPropertyDecl with the DeclContext being
@@ -113,7 +115,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
if (!CCPrimary) {
Diag(CDecl->getLocation(), diag::err_continuation_class);
*isOverridingProperty = true;
- return DeclPtrTy();
+ return 0;
}
// Find the property in continuation class's primary class only.
@@ -136,7 +138,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
// is not what it was meant for. However, gcc supports it and so should we.
// Make sure setter/getters are declared here.
ProcessPropertyDecl(PDecl, CCPrimary);
- return DeclPtrTy::make(PDecl);
+ return PDecl;
}
@@ -165,13 +167,13 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
PIkind);
- DeclPtrTy ProtocolPtrTy =
+ Decl *ProtocolPtrTy =
ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
PIDecl->getGetterName(),
PIDecl->getSetterName(),
- DeclPtrTy::make(CCPrimary), isOverridingProperty,
+ CCPrimary, isOverridingProperty,
MethodImplKind);
- PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>());
+ PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
}
PIDecl->makeitReadWriteAttribute();
if (Attributes & ObjCDeclSpec::DQ_PR_retain)
@@ -187,7 +189,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
*isOverridingProperty = true;
// Make sure setter decl is synthesized, and added to primary class's list.
ProcessPropertyDecl(PIDecl, CCPrimary);
- return DeclPtrTy();
+ return 0;
}
ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
@@ -289,19 +291,19 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
/// builds the AST node for a property implementation declaration; declared
/// as @synthesize or @dynamic.
///
-Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
- SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool Synthesize,
- DeclPtrTy ClassCatImpDecl,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar) {
+Decl *Sema::ActOnPropertyImplDecl(Scope *S,
+ SourceLocation AtLoc,
+ SourceLocation PropertyLoc,
+ bool Synthesize,
+ Decl *ClassCatImpDecl,
+ IdentifierInfo *PropertyId,
+ IdentifierInfo *PropertyIvar) {
ObjCContainerDecl *ClassImpDecl =
- cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>());
+ cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
// Make sure we have a context for the property implementation declaration.
if (!ClassImpDecl) {
Diag(AtLoc, diag::error_missing_property_context);
- return DeclPtrTy();
+ return 0;
}
ObjCPropertyDecl *property = 0;
ObjCInterfaceDecl* IDecl = 0;
@@ -320,25 +322,25 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
property = IDecl->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
- return DeclPtrTy();
+ return 0;
}
if (const ObjCCategoryDecl *CD =
dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
if (!CD->IsClassExtension()) {
Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
Diag(property->getLocation(), diag::note_property_declare);
- return DeclPtrTy();
+ return 0;
}
}
} else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
if (Synthesize) {
Diag(AtLoc, diag::error_synthesize_category_decl);
- return DeclPtrTy();
+ return 0;
}
IDecl = CatImplClass->getClassInterface();
if (!IDecl) {
Diag(AtLoc, diag::error_missing_property_interface);
- return DeclPtrTy();
+ return 0;
}
ObjCCategoryDecl *Category =
IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
@@ -346,17 +348,17 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
// If category for this implementation not found, it is an error which
// has already been reported eralier.
if (!Category)
- return DeclPtrTy();
+ return 0;
// Look for this property declaration in @implementation's category
property = Category->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_category_property_decl)
<< Category->getDeclName();
- return DeclPtrTy();
+ return 0;
}
} else {
Diag(AtLoc, diag::error_bad_property_context);
- return DeclPtrTy();
+ return 0;
}
ObjCIvarDecl *Ivar = 0;
// Check that we have a valid, previously declared ivar for @synthesize
@@ -372,7 +374,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
PropertyIvar, PropType, /*Dinfo=*/0,
ObjCIvarDecl::Protected,
- (Expr *)0);
+ (Expr *)0, true);
ClassImpDecl->addDecl(Ivar);
IDecl->makeDeclVisibleInContext(Ivar, false);
property->setPropertyIvarDecl(Ivar);
@@ -387,7 +389,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
<< property->getDeclName() << Ivar->getDeclName()
<< ClassDeclared->getDeclName();
Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
- << Ivar << Ivar->getNameAsCString();
+ << Ivar << Ivar->getName();
// Note! I deliberately want it to fall thru so more errors are caught.
}
QualType IvarType = Context.getCanonicalType(Ivar->getType());
@@ -464,7 +466,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
Expr *IvarRefExpr =
new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
SelfExpr, true, true);
- OwningExprResult Res =
+ ExprResult Res =
PerformCopyInitialization(InitializedEntity::InitializeResult(
SourceLocation(),
getterMethod->getResultType(),
@@ -494,8 +496,8 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
ParmVarDecl *Param = (*P);
Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
SourceLocation());
- OwningExprResult Res = BuildBinOp(S, SourceLocation(),
- BinaryOperator::Assign, lhs, rhs);
+ ExprResult Res = BuildBinOp(S, SourceLocation(),
+ BO_Assign, lhs, rhs);
PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
}
}
@@ -514,9 +516,29 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
= IC->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
- return DeclPtrTy();
+ return 0;
}
IC->addPropertyImplementation(PIDecl);
+ if (getLangOptions().ObjCNonFragileABI2) {
+ // Diagnose if an ivar was lazily synthesdized due to a previous
+ // use and if 1) property is @dynamic or 2) property is synthesized
+ // but it requires an ivar of different name.
+ ObjCInterfaceDecl *ClassDeclared;
+ ObjCIvarDecl *Ivar = 0;
+ if (!Synthesize)
+ Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+ else {
+ if (PropertyIvar && PropertyIvar != PropertyId)
+ Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+ }
+ // Issue diagnostics only if Ivar belongs to current class.
+ if (Ivar && Ivar->getSynthesize() &&
+ IC->getClassInterface() == ClassDeclared) {
+ Diag(Ivar->getLocation(), diag::err_undeclared_var_use)
+ << PropertyId;
+ Ivar->setInvalidDecl();
+ }
+ }
} else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
@@ -531,12 +553,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
CatImplClass->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
- return DeclPtrTy();
+ return 0;
}
CatImplClass->addPropertyImplementation(PIDecl);
}
- return DeclPtrTy::make(PIDecl);
+ return PIDecl;
}
//===----------------------------------------------------------------------===//
@@ -680,9 +702,8 @@ Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl,
/// declared in 'ClassOrProtocol' objects (which can be a class or an
/// inherited protocol with the list of properties for class/category 'CDecl'
///
-void Sema::CompareProperties(Decl *CDecl,
- DeclPtrTy ClassOrProtocol) {
- Decl *ClassDecl = ClassOrProtocol.getAs<Decl>();
+void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) {
+ Decl *ClassDecl = ClassOrProtocol;
ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
if (!IDecl) {
@@ -699,7 +720,7 @@ void Sema::CompareProperties(Decl *CDecl,
// their properties with those in the category.
for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
E = CatDecl->protocol_end(); P != E; ++P)
- CompareProperties(CatDecl, DeclPtrTy::make(*P));
+ CompareProperties(CatDecl, *P);
} else {
ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -710,16 +731,18 @@ void Sema::CompareProperties(Decl *CDecl,
}
if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
- for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
- E = MDecl->protocol_end(); P != E; ++P)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ P = MDecl->all_referenced_protocol_begin(),
+ E = MDecl->all_referenced_protocol_end(); P != E; ++P)
// Match properties of class IDecl with those of protocol (*P).
MatchOneProtocolPropertiesInClass(IDecl, *P);
// Go thru the list of protocols for this class and recursively match
// their properties with those declared in the class.
- for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
- E = IDecl->protocol_end(); P != E; ++P)
- CompareProperties(IDecl, DeclPtrTy::make(*P));
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ P = IDecl->all_referenced_protocol_begin(),
+ E = IDecl->all_referenced_protocol_end(); P != E; ++P)
+ CompareProperties(IDecl, *P);
} else {
ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -791,8 +814,9 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
PropMap[Prop->getIdentifier()] = Prop;
}
// scan through class's protocols.
- for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
- E = IDecl->protocol_end(); PI != E; ++PI)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = IDecl->all_referenced_protocol_begin(),
+ E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
CollectImmediateProperties((*PI), PropMap, SuperPropMap);
}
if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
@@ -803,7 +827,7 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
PropMap[Prop->getIdentifier()] = Prop;
}
// scan through class's protocols.
- for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
+ for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(),
E = CATDecl->protocol_end(); PI != E; ++PI)
CollectImmediateProperties((*PI), PropMap, SuperPropMap);
}
@@ -838,8 +862,9 @@ static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl,
ObjCPropertyDecl *Prop = (*P);
PropMap[Prop->getIdentifier()] = Prop;
}
- for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
- E = IDecl->protocol_end(); PI != E; ++PI)
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = IDecl->all_referenced_protocol_begin(),
+ E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
CollectClassPropertyImplementations((*PI), PropMap);
}
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
@@ -881,8 +906,9 @@ ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
return Prop;
}
// scan through class's protocols.
- for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
- E = IDecl->protocol_end(); PI != E; ++PI) {
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = IDecl->all_referenced_protocol_begin(),
+ E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) {
ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
if (Prop)
return Prop;
@@ -933,9 +959,15 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
// Property may have been synthesized by user.
if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier()))
continue;
+ if (IMPDecl->getInstanceMethod(Prop->getGetterName())) {
+ if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
+ continue;
+ if (IMPDecl->getInstanceMethod(Prop->getSetterName()))
+ continue;
+ }
ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(),
- true, DeclPtrTy::make(IMPDecl),
+ true, IMPDecl,
Prop->getIdentifier(), Prop->getIdentifier());
}
}
@@ -1066,7 +1098,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
// for this class.
GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(), property->getGetterName(),
- property->getType(), 0, CD, true, false, true,
+ property->getType(), 0, CD, true, false, true,
+ false,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
@@ -1094,6 +1127,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
property->getLocation(),
property->getSetterName(),
Context.VoidTy, 0, CD, true, false, true,
+ false,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
@@ -1105,8 +1139,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
property->getIdentifier(),
property->getType(),
/*TInfo=*/0,
- VarDecl::None,
- VarDecl::None,
+ SC_None,
+ SC_None,
0);
SetterMethod->setMethodParams(Context, &Argument, 1, 1);
CD->addDecl(SetterMethod);
@@ -1138,11 +1172,10 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
AddInstanceMethodToGlobalPool(SetterMethod);
}
-void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
+void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
SourceLocation Loc,
unsigned &Attributes) {
// FIXME: Improve the reported location.
- Decl *PDecl = PropertyPtrTy.getAs<Decl>();
if (!PDecl)
return;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index c4ab9061b445..11b4bb3b92c6 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -11,13 +11,16 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeOrdering.h"
@@ -27,6 +30,34 @@
#include <algorithm>
namespace clang {
+using namespace sema;
+
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS);
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+ UserDefinedConversionSequence& User,
+ OverloadCandidateSet& Conversions,
+ bool AllowExplicit);
+
+
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareQualificationConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareDerivedToBaseConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2);
+
+
/// GetConversionCategory - Retrieve the implicit conversion
/// category corresponding to the given implicit conversion kind.
@@ -298,7 +329,7 @@ namespace {
OverloadCandidate::DeductionFailureInfo
static MakeDeductionFailureInfo(ASTContext &Context,
Sema::TemplateDeductionResult TDK,
- Sema::TemplateDeductionInfo &Info) {
+ TemplateDeductionInfo &Info) {
OverloadCandidate::DeductionFailureInfo Result;
Result.Result = static_cast<unsigned>(TDK);
Result.Data = 0;
@@ -315,7 +346,7 @@ static MakeDeductionFailureInfo(ASTContext &Context,
break;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals: {
+ case Sema::TDK_Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
Saved->Param = Info.Param;
@@ -348,7 +379,7 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() {
break;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
// FIXME: Destroy the data?
Data = 0;
break;
@@ -380,7 +411,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
return TemplateParameter::getFromOpaqueValue(Data);
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return static_cast<DFIParamWithArguments*>(Data)->Param;
// Unhandled
@@ -402,7 +433,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return 0;
case Sema::TDK_SubstitutionFailure:
@@ -429,7 +460,7 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
return 0;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
// Unhandled
@@ -454,7 +485,7 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
return 0;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
// Unhandled
@@ -573,6 +604,11 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
bool UseUsingDeclRules) {
+ // If both of the functions are extern "C", then they are not
+ // overloads.
+ if (Old->isExternC() && New->isExternC())
+ return false;
+
FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
@@ -669,40 +705,34 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
/// not permitted.
/// If @p AllowExplicit, then explicit user-defined conversions are
/// permitted.
-ImplicitConversionSequence
-Sema::TryImplicitConversion(Expr* From, QualType ToType,
- bool SuppressUserConversions,
- bool AllowExplicit,
- bool InOverloadResolution) {
+static ImplicitConversionSequence
+TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
+ bool SuppressUserConversions,
+ bool AllowExplicit,
+ bool InOverloadResolution) {
ImplicitConversionSequence ICS;
- if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) {
+ if (IsStandardConversion(S, From, ToType, InOverloadResolution,
+ ICS.Standard)) {
ICS.setStandard();
return ICS;
}
- if (!getLangOptions().CPlusPlus) {
+ if (!S.getLangOptions().CPlusPlus) {
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
return ICS;
}
- if (SuppressUserConversions) {
- // C++ [over.ics.user]p4:
- // A conversion of an expression of class type to the same class
- // type is given Exact Match rank, and a conversion of an
- // expression of class type to a base class of that type is
- // given Conversion rank, in spite of the fact that a copy/move
- // constructor (i.e., a user-defined conversion function) is
- // called for those cases.
- QualType FromType = From->getType();
- if (!ToType->getAs<RecordType>() || !FromType->getAs<RecordType>() ||
- !(Context.hasSameUnqualifiedType(FromType, ToType) ||
- IsDerivedFrom(FromType, ToType))) {
- // We're not in the case above, so there is no conversion that
- // we can perform.
- ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
- return ICS;
- }
-
+ // C++ [over.ics.user]p4:
+ // A conversion of an expression of class type to the same class
+ // type is given Exact Match rank, and a conversion of an
+ // expression of class type to a base class of that type is
+ // given Conversion rank, in spite of the fact that a copy/move
+ // constructor (i.e., a user-defined conversion function) is
+ // called for those cases.
+ QualType FromType = From->getType();
+ if (ToType->getAs<RecordType>() && FromType->getAs<RecordType>() &&
+ (S.Context.hasSameUnqualifiedType(FromType, ToType) ||
+ S.IsDerivedFrom(FromType, ToType))) {
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
@@ -713,18 +743,25 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
// exists. When we actually perform initialization, we'll find the
// appropriate constructor to copy the returned object, if needed.
ICS.Standard.CopyConstructor = 0;
-
+
// Determine whether this is considered a derived-to-base conversion.
- if (!Context.hasSameUnqualifiedType(FromType, ToType))
+ if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
ICS.Standard.Second = ICK_Derived_To_Base;
-
+
+ return ICS;
+ }
+
+ if (SuppressUserConversions) {
+ // We're not in the case above, so there is no conversion that
+ // we can perform.
+ ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
return ICS;
}
// Attempt user-defined conversion.
OverloadCandidateSet Conversions(From->getExprLoc());
OverloadingResult UserDefResult
- = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions,
+ = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
AllowExplicit);
if (UserDefResult == OR_Success) {
@@ -739,10 +776,11 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
if (CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
QualType FromCanon
- = Context.getCanonicalType(From->getType().getUnqualifiedType());
- QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+ = S.Context.getCanonicalType(From->getType().getUnqualifiedType());
+ QualType ToCanon
+ = S.Context.getCanonicalType(ToType).getUnqualifiedType();
if (Constructor->isCopyConstructor() &&
- (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
+ (FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) {
// Turn this into a "standard" conversion sequence, so that it
// gets ranked with standard conversion sequences.
ICS.setStandard();
@@ -780,6 +818,24 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
return ICS;
}
+bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
+ const InitializedEntity &Entity,
+ Expr *Initializer,
+ bool SuppressUserConversions,
+ bool AllowExplicitConversions,
+ bool InOverloadResolution) {
+ ImplicitConversionSequence ICS
+ = clang::TryImplicitConversion(*this, Initializer, Entity.getType(),
+ SuppressUserConversions,
+ AllowExplicitConversions,
+ InOverloadResolution);
+ if (ICS.isBad()) return true;
+
+ // Perform the actual conversion.
+ Sequence.AddConversionSequenceStep(ICS, Entity.getType());
+ return false;
+}
+
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType. Returns true if there was an
/// error, false otherwise. The expression From is replaced with the
@@ -797,10 +853,10 @@ bool
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
- ICS = TryImplicitConversion(From, ToType,
- /*SuppressUserConversions=*/false,
- AllowExplicit,
- /*InOverloadResolution=*/false);
+ ICS = clang::TryImplicitConversion(*this, From, ToType,
+ /*SuppressUserConversions=*/false,
+ AllowExplicit,
+ /*InOverloadResolution=*/false);
return PerformImplicitConversion(From, ToType, ICS, Action);
}
@@ -850,16 +906,20 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType,
return true;
}
}
-
- // If lax vector conversions are permitted and the vector types are of the
- // same size, we can perform the conversion.
- if (Context.getLangOptions().LaxVectorConversions &&
- FromType->isVectorType() && ToType->isVectorType() &&
- Context.getTypeSize(FromType) == Context.getTypeSize(ToType)) {
- ICK = ICK_Vector_Conversion;
- return true;
+
+ // We can perform the conversion between vector types in the following cases:
+ // 1)vector types are equivalent AltiVec and GCC vector types
+ // 2)lax vector conversions are permitted and the vector types are of the
+ // same size
+ if (ToType->isVectorType() && FromType->isVectorType()) {
+ if (Context.areCompatibleVectorTypes(FromType, ToType) ||
+ (Context.getLangOptions().LaxVectorConversions &&
+ (Context.getTypeSize(FromType) == Context.getTypeSize(ToType)))) {
+ ICK = ICK_Vector_Conversion;
+ return true;
+ }
}
-
+
return false;
}
@@ -871,12 +931,11 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType,
/// contain the standard conversion sequence required to perform this
/// conversion and this routine will return true. Otherwise, this
/// routine will return false and the value of SCS is unspecified.
-bool
-Sema::IsStandardConversion(Expr* From, QualType ToType,
- bool InOverloadResolution,
- StandardConversionSequence &SCS) {
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS) {
QualType FromType = From->getType();
-
+
// Standard conversions (C++ [conv])
SCS.setAsIdentityConversion();
SCS.DeprecatedStringLiteralToCharPtr = false;
@@ -887,7 +946,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// There are no standard conversions for class types in C++, so
// abort early. When overloading in C, however, we do permit
if (FromType->isRecordType() || ToType->isRecordType()) {
- if (getLangOptions().CPlusPlus)
+ if (S.getLangOptions().CPlusPlus)
return false;
// When we're overloading in C, we allow, as standard conversions,
@@ -897,19 +956,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// array-to-pointer conversion, or function-to-pointer conversion
// (C++ 4p1).
- if (FromType == Context.OverloadTy) {
+ if (FromType == S.Context.OverloadTy) {
DeclAccessPair AccessPair;
if (FunctionDecl *Fn
- = ResolveAddressOfOverloadedFunction(From, ToType, false,
- AccessPair)) {
+ = S.ResolveAddressOfOverloadedFunction(From, ToType, false,
+ AccessPair)) {
// We were able to resolve the address of the overloaded function,
// so we can convert to the type of that function.
FromType = Fn->getType();
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
if (!Method->isStatic()) {
Type *ClassType
- = Context.getTypeDeclType(Method->getParent()).getTypePtr();
- FromType = Context.getMemberPointerType(FromType, ClassType);
+ = S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
+ FromType = S.Context.getMemberPointerType(FromType, ClassType);
}
}
@@ -917,12 +976,12 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// function, update the type of the resulting expression accordingly.
if (FromType->getAs<FunctionType>())
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens()))
- if (UnOp->getOpcode() == UnaryOperator::AddrOf)
- FromType = Context.getPointerType(FromType);
+ if (UnOp->getOpcode() == UO_AddrOf)
+ FromType = S.Context.getPointerType(FromType);
// Check that we've computed the proper type after overload resolution.
- assert(Context.hasSameType(FromType,
- FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
+ assert(S.Context.hasSameType(FromType,
+ S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
} else {
return false;
}
@@ -930,10 +989,10 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// Lvalue-to-rvalue conversion (C++ 4.1):
// An lvalue (3.10) of a non-function, non-array type T can be
// converted to an rvalue.
- Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
+ Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
if (argIsLvalue == Expr::LV_Valid &&
!FromType->isFunctionType() && !FromType->isArrayType() &&
- Context.getCanonicalType(FromType) != Context.OverloadTy) {
+ S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
SCS.First = ICK_Lvalue_To_Rvalue;
// If T is a non-class type, the type of the rvalue is the
@@ -948,9 +1007,9 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// An lvalue or rvalue of type "array of N T" or "array of unknown
// bound of T" can be converted to an rvalue of type "pointer to
// T" (C++ 4.2p1).
- FromType = Context.getArrayDecayedType(FromType);
+ FromType = S.Context.getArrayDecayedType(FromType);
- if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
+ if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
// This conversion is deprecated. (C++ D.4).
SCS.DeprecatedStringLiteralToCharPtr = true;
@@ -970,7 +1029,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// An lvalue of function type T can be converted to an rvalue of
// type "pointer to T." The result is a pointer to the
// function. (C++ 4.3p1).
- FromType = Context.getPointerType(FromType);
+ FromType = S.Context.getPointerType(FromType);
} else {
// We don't require any conversions for the first step.
SCS.First = ICK_Identity;
@@ -985,24 +1044,24 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// conversion.
bool IncompatibleObjC = false;
ImplicitConversionKind SecondICK = ICK_Identity;
- if (Context.hasSameUnqualifiedType(FromType, ToType)) {
+ if (S.Context.hasSameUnqualifiedType(FromType, ToType)) {
// The unqualified versions of the types are the same: there's no
// conversion to do.
SCS.Second = ICK_Identity;
- } else if (IsIntegralPromotion(From, FromType, ToType)) {
+ } else if (S.IsIntegralPromotion(From, FromType, ToType)) {
// Integral promotion (C++ 4.5).
SCS.Second = ICK_Integral_Promotion;
FromType = ToType.getUnqualifiedType();
- } else if (IsFloatingPointPromotion(FromType, ToType)) {
+ } else if (S.IsFloatingPointPromotion(FromType, ToType)) {
// Floating point promotion (C++ 4.6).
SCS.Second = ICK_Floating_Promotion;
FromType = ToType.getUnqualifiedType();
- } else if (IsComplexPromotion(FromType, ToType)) {
+ } else if (S.IsComplexPromotion(FromType, ToType)) {
// Complex promotion (Clang extension)
SCS.Second = ICK_Complex_Promotion;
FromType = ToType.getUnqualifiedType();
} else if (FromType->isIntegralOrEnumerationType() &&
- ToType->isIntegralType(Context)) {
+ ToType->isIntegralType(S.Context)) {
// Integral conversions (C++ 4.7).
SCS.Second = ICK_Integral_Conversion;
FromType = ToType.getUnqualifiedType();
@@ -1020,19 +1079,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
} else if ((FromType->isRealFloatingType() &&
- ToType->isIntegralType(Context) && !ToType->isBooleanType()) ||
+ ToType->isIntegralType(S.Context) && !ToType->isBooleanType()) ||
(FromType->isIntegralOrEnumerationType() &&
ToType->isRealFloatingType())) {
// Floating-integral conversions (C++ 4.9).
SCS.Second = ICK_Floating_Integral;
FromType = ToType.getUnqualifiedType();
- } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
- FromType, IncompatibleObjC)) {
+ } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution,
+ FromType, IncompatibleObjC)) {
// Pointer conversions (C++ 4.10).
SCS.Second = ICK_Pointer_Conversion;
SCS.IncompatibleObjC = IncompatibleObjC;
- } else if (IsMemberPointerConversion(From, FromType, ToType,
- InOverloadResolution, FromType)) {
+ } else if (S.IsMemberPointerConversion(From, FromType, ToType,
+ InOverloadResolution, FromType)) {
// Pointer to member conversions (4.11).
SCS.Second = ICK_Pointer_Member;
} else if (ToType->isBooleanType() &&
@@ -1044,16 +1103,16 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
FromType->isNullPtrType())) {
// Boolean conversions (C++ 4.12).
SCS.Second = ICK_Boolean_Conversion;
- FromType = Context.BoolTy;
- } else if (IsVectorConversion(Context, FromType, ToType, SecondICK)) {
+ FromType = S.Context.BoolTy;
+ } else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
SCS.Second = SecondICK;
FromType = ToType.getUnqualifiedType();
- } else if (!getLangOptions().CPlusPlus &&
- Context.typesAreCompatible(ToType, FromType)) {
+ } else if (!S.getLangOptions().CPlusPlus &&
+ S.Context.typesAreCompatible(ToType, FromType)) {
// Compatible conversions (Clang extension for C function overloading)
SCS.Second = ICK_Compatible_Conversion;
FromType = ToType.getUnqualifiedType();
- } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+ } else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
// Treat a conversion that strips "noreturn" as an identity conversion.
SCS.Second = ICK_NoReturn_Adjustment;
} else {
@@ -1065,11 +1124,11 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
QualType CanonFrom;
QualType CanonTo;
// The third conversion can be a qualification conversion (C++ 4p1).
- if (IsQualificationConversion(FromType, ToType)) {
+ if (S.IsQualificationConversion(FromType, ToType)) {
SCS.Third = ICK_Qualification;
FromType = ToType;
- CanonFrom = Context.getCanonicalType(FromType);
- CanonTo = Context.getCanonicalType(ToType);
+ CanonFrom = S.Context.getCanonicalType(FromType);
+ CanonTo = S.Context.getCanonicalType(ToType);
} else {
// No conversion required
SCS.Third = ICK_Identity;
@@ -1078,8 +1137,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// [...] Any difference in top-level cv-qualification is
// subsumed by the initialization itself and does not constitute
// a conversion. [...]
- CanonFrom = Context.getCanonicalType(FromType);
- CanonTo = Context.getCanonicalType(ToType);
+ CanonFrom = S.Context.getCanonicalType(FromType);
+ CanonTo = S.Context.getCanonicalType(ToType);
if (CanonFrom.getLocalUnqualifiedType()
== CanonTo.getLocalUnqualifiedType() &&
(CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
@@ -1397,10 +1456,16 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
QualType FromPointeeType = FromTypePtr->getPointeeType();
+ // If the unqualified pointee types are the same, this can't be a
+ // pointer conversion, so don't do all of the work below.
+ if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType))
+ return false;
+
// An rvalue of type "pointer to cv T," where T is an object type,
// can be converted to an rvalue of type "pointer to cv void" (C++
// 4.10p2).
- if (FromPointeeType->isObjectType() && ToPointeeType->isVoidType()) {
+ if (FromPointeeType->isIncompleteOrObjectType() &&
+ ToPointeeType->isVoidType()) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
@@ -1657,8 +1722,8 @@ bool Sema::FunctionArgTypesAreEqual(FunctionProtoType* OldType,
/// true. It returns true and produces a diagnostic if there was an
/// error, or returns false otherwise.
bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray& BasePath,
+ CastKind &Kind,
+ CXXCastPath& BasePath,
bool IgnoreBaseAccess) {
QualType FromType = From->getType();
@@ -1684,7 +1749,7 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
return true;
// The conversion was successful.
- Kind = CastExpr::CK_DerivedToBase;
+ Kind = CK_DerivedToBase;
}
}
if (const ObjCObjectPointerType *FromPtrType =
@@ -1749,8 +1814,8 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
/// true and produces a diagnostic if there was an error, or returns false
/// otherwise.
bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
- CastExpr::CastKind &Kind,
- CXXBaseSpecifierArray &BasePath,
+ CastKind &Kind,
+ CXXCastPath &BasePath,
bool IgnoreBaseAccess) {
QualType FromType = From->getType();
const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
@@ -1759,7 +1824,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
assert(From->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull) &&
"Expr must be null pointer constant!");
- Kind = CastExpr::CK_NullToMemberPointer;
+ Kind = CK_NullToMemberPointer;
return false;
}
@@ -1803,7 +1868,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
// Must be a base to derived member conversion.
BuildBasePathArray(Paths, BasePath);
- Kind = CastExpr::CK_BaseToDerivedMemberPointer;
+ Kind = CK_BaseToDerivedMemberPointer;
return false;
}
@@ -1869,10 +1934,11 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
/// \param AllowExplicit true if the conversion should consider C++0x
/// "explicit" conversion functions as well as non-explicit conversion
/// functions (C++0x [class.conv.fct]p2).
-OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
- UserDefinedConversionSequence& User,
- OverloadCandidateSet& CandidateSet,
- bool AllowExplicit) {
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+ UserDefinedConversionSequence& User,
+ OverloadCandidateSet& CandidateSet,
+ bool AllowExplicit) {
// Whether we will only visit constructors.
bool ConstructorsOnly = false;
@@ -1887,17 +1953,17 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// functions are all the converting constructors (12.3.1) of
// that class. The argument list is the expression-list within
// the parentheses of the initializer.
- if (Context.hasSameUnqualifiedType(ToType, From->getType()) ||
+ if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) ||
(From->getType()->getAs<RecordType>() &&
- IsDerivedFrom(From->getType(), ToType)))
+ S.IsDerivedFrom(From->getType(), ToType)))
ConstructorsOnly = true;
- if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
+ if (S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag())) {
// We're not going to find any constructors.
} else if (CXXRecordDecl *ToRecordDecl
= dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
DeclContext::lookup_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = LookupConstructors(ToRecordDecl);
+ for (llvm::tie(Con, ConEnd) = S.LookupConstructors(ToRecordDecl);
Con != ConEnd; ++Con) {
NamedDecl *D = *Con;
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -1915,16 +1981,18 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
- AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
- /*ExplicitArgs*/ 0,
- &From, 1, CandidateSet,
- /*SuppressUserConversions=*/!ConstructorsOnly);
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+ /*ExplicitArgs*/ 0,
+ &From, 1, CandidateSet,
+ /*SuppressUserConversions=*/
+ !ConstructorsOnly);
else
// Allow one user-defined conversion when user specifies a
// From->ToType conversion via an static cast (c-style, etc).
- AddOverloadCandidate(Constructor, FoundDecl,
- &From, 1, CandidateSet,
- /*SuppressUserConversions=*/!ConstructorsOnly);
+ S.AddOverloadCandidate(Constructor, FoundDecl,
+ &From, 1, CandidateSet,
+ /*SuppressUserConversions=*/
+ !ConstructorsOnly);
}
}
}
@@ -1932,8 +2000,8 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// Enumerate conversion functions, if we're allowed to.
if (ConstructorsOnly) {
- } else if (RequireCompleteType(From->getLocStart(), From->getType(),
- PDiag(0) << From->getSourceRange())) {
+ } else if (S.RequireCompleteType(From->getLocStart(), From->getType(),
+ S.PDiag(0) << From->getSourceRange())) {
// No conversion functions from incomplete types.
} else if (const RecordType *FromRecordType
= From->getType()->getAs<RecordType>()) {
@@ -1959,80 +2027,79 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
- AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
- ActingContext, From, ToType,
- CandidateSet);
+ S.AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
+ ActingContext, From, ToType,
+ CandidateSet);
else
- AddConversionCandidate(Conv, FoundDecl, ActingContext,
- From, ToType, CandidateSet);
+ S.AddConversionCandidate(Conv, FoundDecl, ActingContext,
+ From, ToType, CandidateSet);
}
}
}
}
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, From->getLocStart(), Best)) {
- case OR_Success:
- // Record the standard conversion we used and the conversion function.
- if (CXXConstructorDecl *Constructor
- = dyn_cast<CXXConstructorDecl>(Best->Function)) {
- // C++ [over.ics.user]p1:
- // If the user-defined conversion is specified by a
- // constructor (12.3.1), the initial standard conversion
- // sequence converts the source type to the type required by
- // the argument of the constructor.
- //
- QualType ThisType = Constructor->getThisType(Context);
- if (Best->Conversions[0].isEllipsis())
- User.EllipsisConversion = true;
- else {
- User.Before = Best->Conversions[0].Standard;
- User.EllipsisConversion = false;
- }
- User.ConversionFunction = Constructor;
- User.After.setAsIdentityConversion();
- User.After.setFromType(
- ThisType->getAs<PointerType>()->getPointeeType());
- User.After.setAllToTypes(ToType);
- return OR_Success;
- } else if (CXXConversionDecl *Conversion
- = dyn_cast<CXXConversionDecl>(Best->Function)) {
- // C++ [over.ics.user]p1:
- //
- // [...] If the user-defined conversion is specified by a
- // conversion function (12.3.2), the initial standard
- // conversion sequence converts the source type to the
- // implicit object parameter of the conversion function.
+ switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best)) {
+ case OR_Success:
+ // Record the standard conversion we used and the conversion function.
+ if (CXXConstructorDecl *Constructor
+ = dyn_cast<CXXConstructorDecl>(Best->Function)) {
+ // C++ [over.ics.user]p1:
+ // If the user-defined conversion is specified by a
+ // constructor (12.3.1), the initial standard conversion
+ // sequence converts the source type to the type required by
+ // the argument of the constructor.
+ //
+ QualType ThisType = Constructor->getThisType(S.Context);
+ if (Best->Conversions[0].isEllipsis())
+ User.EllipsisConversion = true;
+ else {
User.Before = Best->Conversions[0].Standard;
- User.ConversionFunction = Conversion;
User.EllipsisConversion = false;
-
- // C++ [over.ics.user]p2:
- // The second standard conversion sequence converts the
- // result of the user-defined conversion to the target type
- // for the sequence. Since an implicit conversion sequence
- // is an initialization, the special rules for
- // initialization by user-defined conversion apply when
- // selecting the best user-defined conversion for a
- // user-defined conversion sequence (see 13.3.3 and
- // 13.3.3.1).
- User.After = Best->FinalConversion;
- return OR_Success;
- } else {
- assert(false && "Not a constructor or conversion function?");
- return OR_No_Viable_Function;
}
-
- case OR_No_Viable_Function:
+ User.ConversionFunction = Constructor;
+ User.After.setAsIdentityConversion();
+ User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
+ User.After.setAllToTypes(ToType);
+ return OR_Success;
+ } else if (CXXConversionDecl *Conversion
+ = dyn_cast<CXXConversionDecl>(Best->Function)) {
+ // C++ [over.ics.user]p1:
+ //
+ // [...] If the user-defined conversion is specified by a
+ // conversion function (12.3.2), the initial standard
+ // conversion sequence converts the source type to the
+ // implicit object parameter of the conversion function.
+ User.Before = Best->Conversions[0].Standard;
+ User.ConversionFunction = Conversion;
+ User.EllipsisConversion = false;
+
+ // C++ [over.ics.user]p2:
+ // The second standard conversion sequence converts the
+ // result of the user-defined conversion to the target type
+ // for the sequence. Since an implicit conversion sequence
+ // is an initialization, the special rules for
+ // initialization by user-defined conversion apply when
+ // selecting the best user-defined conversion for a
+ // user-defined conversion sequence (see 13.3.3 and
+ // 13.3.3.1).
+ User.After = Best->FinalConversion;
+ return OR_Success;
+ } else {
+ llvm_unreachable("Not a constructor or conversion function?");
return OR_No_Viable_Function;
- case OR_Deleted:
- // No conversion here! We're done.
- return OR_Deleted;
-
- case OR_Ambiguous:
- return OR_Ambiguous;
}
+ case OR_No_Viable_Function:
+ return OR_No_Viable_Function;
+ case OR_Deleted:
+ // No conversion here! We're done.
+ return OR_Deleted;
+
+ case OR_Ambiguous:
+ return OR_Ambiguous;
+ }
+
return OR_No_Viable_Function;
}
@@ -2041,7 +2108,7 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
ImplicitConversionSequence ICS;
OverloadCandidateSet CandidateSet(From->getExprLoc());
OverloadingResult OvResult =
- IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+ IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
CandidateSet, false);
if (OvResult == OR_Ambiguous)
Diag(From->getSourceRange().getBegin(),
@@ -2053,16 +2120,17 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
<< From->getType() << ToType << From->getSourceRange();
else
return false;
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &From, 1);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &From, 1);
return true;
}
/// CompareImplicitConversionSequences - Compare two implicit
/// conversion sequences to determine whether one is better than the
/// other or if they are indistinguishable (C++ 13.3.3.2).
-ImplicitConversionSequence::CompareKind
-Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
- const ImplicitConversionSequence& ICS2)
+static ImplicitConversionSequence::CompareKind
+CompareImplicitConversionSequences(Sema &S,
+ const ImplicitConversionSequence& ICS1,
+ const ImplicitConversionSequence& ICS2)
{
// (C++ 13.3.3.2p2): When comparing the basic forms of implicit
// conversion sequences (as defined in 13.3.3.1)
@@ -2092,7 +2160,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
// indistinguishable conversion sequences unless one of the
// following rules apply: (C++ 13.3.3.2p3):
if (ICS1.isStandard())
- return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
+ return CompareStandardConversionSequences(S, ICS1.Standard, ICS2.Standard);
else if (ICS1.isUserDefined()) {
// User-defined conversion sequence U1 is a better conversion
// sequence than another user-defined conversion sequence U2 if
@@ -2102,7 +2170,8 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
// U2 (C++ 13.3.3.2p3).
if (ICS1.UserDefined.ConversionFunction ==
ICS2.UserDefined.ConversionFunction)
- return CompareStandardConversionSequences(ICS1.UserDefined.After,
+ return CompareStandardConversionSequences(S,
+ ICS1.UserDefined.After,
ICS2.UserDefined.After);
}
@@ -2168,9 +2237,10 @@ compareStandardConversionSubsets(ASTContext &Context,
/// CompareStandardConversionSequences - Compare two standard
/// conversion sequences to determine whether one is better than the
/// other or if they are indistinguishable (C++ 13.3.3.2p3).
-ImplicitConversionSequence::CompareKind
-Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2)
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2)
{
// Standard conversion sequence S1 is a better conversion sequence
// than standard conversion sequence S2 if (C++ 13.3.3.2p3):
@@ -2181,7 +2251,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// sequence is considered to be a subsequence of any
// non-identity conversion sequence) or, if not that,
if (ImplicitConversionSequence::CompareKind CK
- = compareStandardConversionSubsets(Context, SCS1, SCS2))
+ = compareStandardConversionSubsets(S.Context, SCS1, SCS2))
return CK;
// -- the rank of S1 is better than the rank of S2 (by the rules
@@ -2212,9 +2282,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// void*, and conversion of A* to void* is better than conversion
// of B* to void*.
bool SCS1ConvertsToVoid
- = SCS1.isPointerConversionToVoidPointer(Context);
+ = SCS1.isPointerConversionToVoidPointer(S.Context);
bool SCS2ConvertsToVoid
- = SCS2.isPointerConversionToVoidPointer(Context);
+ = SCS2.isPointerConversionToVoidPointer(S.Context);
if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) {
// Exactly one of the conversion sequences is a conversion to
// a void pointer; it's the worse conversion.
@@ -2224,7 +2294,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// Neither conversion sequence converts to a void pointer; compare
// their derived-to-base conversions.
if (ImplicitConversionSequence::CompareKind DerivedCK
- = CompareDerivedToBaseConversions(SCS1, SCS2))
+ = CompareDerivedToBaseConversions(S, SCS1, SCS2))
return DerivedCK;
} else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid) {
// Both conversion sequences are conversions to void
@@ -2236,18 +2306,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// Adjust the types we're converting from via the array-to-pointer
// conversion, if we need to.
if (SCS1.First == ICK_Array_To_Pointer)
- FromType1 = Context.getArrayDecayedType(FromType1);
+ FromType1 = S.Context.getArrayDecayedType(FromType1);
if (SCS2.First == ICK_Array_To_Pointer)
- FromType2 = Context.getArrayDecayedType(FromType2);
+ FromType2 = S.Context.getArrayDecayedType(FromType2);
QualType FromPointee1
= FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
QualType FromPointee2
= FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
- if (IsDerivedFrom(FromPointee2, FromPointee1))
+ if (S.IsDerivedFrom(FromPointee2, FromPointee1))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(FromPointee1, FromPointee2))
+ else if (S.IsDerivedFrom(FromPointee1, FromPointee2))
return ImplicitConversionSequence::Worse;
// Objective-C++: If one interface is more specific than the
@@ -2255,9 +2325,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
if (FromIface1 && FromIface1) {
- if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+ if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
return ImplicitConversionSequence::Better;
- else if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+ else if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
return ImplicitConversionSequence::Worse;
}
}
@@ -2265,7 +2335,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// Compare based on qualification conversions (C++ 13.3.3.2p3,
// bullet 3).
if (ImplicitConversionSequence::CompareKind QualCK
- = CompareQualificationConversions(SCS1, SCS2))
+ = CompareQualificationConversions(S, SCS1, SCS2))
return QualCK;
if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
@@ -2289,18 +2359,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// to which the reference initialized by S1 refers.
QualType T1 = SCS1.getToType(2);
QualType T2 = SCS2.getToType(2);
- T1 = Context.getCanonicalType(T1);
- T2 = Context.getCanonicalType(T2);
+ T1 = S.Context.getCanonicalType(T1);
+ T2 = S.Context.getCanonicalType(T2);
Qualifiers T1Quals, T2Quals;
- QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
- QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+ QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+ QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
if (UnqualT1 == UnqualT2) {
// If the type is an array type, promote the element qualifiers to the type
// for comparison.
if (isa<ArrayType>(T1) && T1Quals)
- T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+ T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
if (isa<ArrayType>(T2) && T2Quals)
- T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+ T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
if (T2.isMoreQualifiedThan(T1))
return ImplicitConversionSequence::Better;
else if (T1.isMoreQualifiedThan(T2))
@@ -2315,8 +2385,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
/// sequences to determine whether they can be ranked based on their
/// qualification conversions (C++ 13.3.3.2p3 bullet 3).
ImplicitConversionSequence::CompareKind
-Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2) {
+CompareQualificationConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2) {
// C++ 13.3.3.2p3:
// -- S1 and S2 differ only in their qualification conversion and
// yield similar types T1 and T2 (C++ 4.4), respectively, and the
@@ -2331,11 +2402,11 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
// conversion (!)
QualType T1 = SCS1.getToType(2);
QualType T2 = SCS2.getToType(2);
- T1 = Context.getCanonicalType(T1);
- T2 = Context.getCanonicalType(T2);
+ T1 = S.Context.getCanonicalType(T1);
+ T2 = S.Context.getCanonicalType(T2);
Qualifiers T1Quals, T2Quals;
- QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
- QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+ QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+ QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
// If the types are the same, we won't learn anything by unwrapped
// them.
@@ -2345,13 +2416,13 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
// If the type is an array type, promote the element qualifiers to the type
// for comparison.
if (isa<ArrayType>(T1) && T1Quals)
- T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+ T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
if (isa<ArrayType>(T2) && T2Quals)
- T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+ T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
ImplicitConversionSequence::CompareKind Result
= ImplicitConversionSequence::Indistinguishable;
- while (Context.UnwrapSimilarPointerTypes(T1, T2)) {
+ while (S.Context.UnwrapSimilarPointerTypes(T1, T2)) {
// Within each iteration of the loop, we check the qualifiers to
// determine if this still looks like a qualification
// conversion. Then, if all is well, we unwrap one more level of
@@ -2386,7 +2457,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
}
// If the types after this point are equivalent, we're done.
- if (Context.hasSameUnqualifiedType(T1, T2))
+ if (S.Context.hasSameUnqualifiedType(T1, T2))
break;
}
@@ -2416,8 +2487,9 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
/// [over.ics.rank]p4b3). As part of these checks, we also look at
/// conversions between Objective-C interface types.
ImplicitConversionSequence::CompareKind
-Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2) {
+CompareDerivedToBaseConversions(Sema &S,
+ const StandardConversionSequence& SCS1,
+ const StandardConversionSequence& SCS2) {
QualType FromType1 = SCS1.getFromType();
QualType ToType1 = SCS1.getToType(1);
QualType FromType2 = SCS2.getFromType();
@@ -2426,15 +2498,15 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// Adjust the types we're converting from via the array-to-pointer
// conversion, if we need to.
if (SCS1.First == ICK_Array_To_Pointer)
- FromType1 = Context.getArrayDecayedType(FromType1);
+ FromType1 = S.Context.getArrayDecayedType(FromType1);
if (SCS2.First == ICK_Array_To_Pointer)
- FromType2 = Context.getArrayDecayedType(FromType2);
+ FromType2 = S.Context.getArrayDecayedType(FromType2);
// Canonicalize all of the types.
- FromType1 = Context.getCanonicalType(FromType1);
- ToType1 = Context.getCanonicalType(ToType1);
- FromType2 = Context.getCanonicalType(FromType2);
- ToType2 = Context.getCanonicalType(ToType2);
+ FromType1 = S.Context.getCanonicalType(FromType1);
+ ToType1 = S.Context.getCanonicalType(ToType1);
+ FromType2 = S.Context.getCanonicalType(FromType2);
+ ToType2 = S.Context.getCanonicalType(ToType2);
// C++ [over.ics.rank]p4b3:
//
@@ -2466,30 +2538,30 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// -- conversion of C* to B* is better than conversion of C* to A*,
if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
- if (IsDerivedFrom(ToPointee1, ToPointee2))
+ if (S.IsDerivedFrom(ToPointee1, ToPointee2))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(ToPointee2, ToPointee1))
+ else if (S.IsDerivedFrom(ToPointee2, ToPointee1))
return ImplicitConversionSequence::Worse;
if (ToIface1 && ToIface2) {
- if (Context.canAssignObjCInterfaces(ToIface2, ToIface1))
+ if (S.Context.canAssignObjCInterfaces(ToIface2, ToIface1))
return ImplicitConversionSequence::Better;
- else if (Context.canAssignObjCInterfaces(ToIface1, ToIface2))
+ else if (S.Context.canAssignObjCInterfaces(ToIface1, ToIface2))
return ImplicitConversionSequence::Worse;
}
}
// -- conversion of B* to A* is better than conversion of C* to A*,
if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) {
- if (IsDerivedFrom(FromPointee2, FromPointee1))
+ if (S.IsDerivedFrom(FromPointee2, FromPointee1))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(FromPointee1, FromPointee2))
+ else if (S.IsDerivedFrom(FromPointee1, FromPointee2))
return ImplicitConversionSequence::Worse;
if (FromIface1 && FromIface2) {
- if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+ if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
return ImplicitConversionSequence::Better;
- else if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+ else if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
return ImplicitConversionSequence::Worse;
}
}
@@ -2517,16 +2589,16 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType();
// conversion of A::* to B::* is better than conversion of A::* to C::*,
if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
- if (IsDerivedFrom(ToPointee1, ToPointee2))
+ if (S.IsDerivedFrom(ToPointee1, ToPointee2))
return ImplicitConversionSequence::Worse;
- else if (IsDerivedFrom(ToPointee2, ToPointee1))
+ else if (S.IsDerivedFrom(ToPointee2, ToPointee1))
return ImplicitConversionSequence::Better;
}
// conversion of B::* to C::* is better than conversion of A::* to C::*
if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) {
- if (IsDerivedFrom(FromPointee1, FromPointee2))
+ if (S.IsDerivedFrom(FromPointee1, FromPointee2))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(FromPointee2, FromPointee1))
+ else if (S.IsDerivedFrom(FromPointee2, FromPointee1))
return ImplicitConversionSequence::Worse;
}
}
@@ -2536,11 +2608,11 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// -- binding of an expression of type C to a reference of type
// B& is better than binding an expression of type C to a
// reference of type A&,
- if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
- !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
- if (IsDerivedFrom(ToType1, ToType2))
+ if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+ if (S.IsDerivedFrom(ToType1, ToType2))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(ToType2, ToType1))
+ else if (S.IsDerivedFrom(ToType2, ToType1))
return ImplicitConversionSequence::Worse;
}
@@ -2548,11 +2620,11 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// -- binding of an expression of type B to a reference of type
// A& is better than binding an expression of type C to a
// reference of type A&,
- if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
- Context.hasSameUnqualifiedType(ToType1, ToType2)) {
- if (IsDerivedFrom(FromType2, FromType1))
+ if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+ if (S.IsDerivedFrom(FromType2, FromType1))
return ImplicitConversionSequence::Better;
- else if (IsDerivedFrom(FromType1, FromType2))
+ else if (S.IsDerivedFrom(FromType1, FromType2))
return ImplicitConversionSequence::Worse;
}
}
@@ -2570,7 +2642,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
Sema::ReferenceCompareResult
Sema::CompareReferenceRelationship(SourceLocation Loc,
QualType OrigT1, QualType OrigT2,
- bool& DerivedToBase) {
+ bool &DerivedToBase,
+ bool &ObjCConversion) {
assert(!OrigT1->isReferenceType() &&
"T1 must be the pointee type of the reference type");
assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type");
@@ -2585,11 +2658,17 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
// Given types "cv1 T1" and "cv2 T2," "cv1 T1" is
// reference-related to "cv2 T2" if T1 is the same type as T2, or
// T1 is a base class of T2.
- if (UnqualT1 == UnqualT2)
- DerivedToBase = false;
- else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
+ DerivedToBase = false;
+ ObjCConversion = false;
+ if (UnqualT1 == UnqualT2) {
+ // Nothing to do.
+ } else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
IsDerivedFrom(UnqualT2, UnqualT1))
DerivedToBase = true;
+ else if (UnqualT1->isObjCObjectOrInterfaceType() &&
+ UnqualT2->isObjCObjectOrInterfaceType() &&
+ Context.canBindObjCObjectType(UnqualT1, UnqualT2))
+ ObjCConversion = true;
else
return Ref_Incompatible;
@@ -2618,16 +2697,21 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
return Ref_Related;
}
-/// \brief Look for a user-defined conversion to an lvalue reference-compatible
+/// \brief Look for a user-defined conversion to an value reference-compatible
/// with DeclType. Return true if something definite is found.
static bool
-FindConversionToLValue(Sema &S, ImplicitConversionSequence &ICS,
- QualType DeclType, SourceLocation DeclLoc,
- Expr *Init, QualType T2, bool AllowExplicit) {
+FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
+ QualType DeclType, SourceLocation DeclLoc,
+ Expr *Init, QualType T2, bool AllowRvalues,
+ bool AllowExplicit) {
assert(T2->isRecordType() && "Can only find conversions of record types.");
CXXRecordDecl *T2RecordDecl
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
+ QualType ToType
+ = AllowRvalues? DeclType->getAs<ReferenceType>()->getPointeeType()
+ : DeclType;
+
OverloadCandidateSet CandidateSet(DeclLoc);
const UnresolvedSetImpl *Conversions
= T2RecordDecl->getVisibleConversionFunctions();
@@ -2646,25 +2730,44 @@ FindConversionToLValue(Sema &S, ImplicitConversionSequence &ICS,
else
Conv = cast<CXXConversionDecl>(D);
- // If the conversion function doesn't return a reference type,
- // it can't be considered for this conversion. An rvalue reference
- // is only acceptable if its referencee is a function type.
- const ReferenceType *RefType =
- Conv->getConversionType()->getAs<ReferenceType>();
- if (RefType && (RefType->isLValueReferenceType() ||
- RefType->getPointeeType()->isFunctionType()) &&
- (AllowExplicit || !Conv->isExplicit())) {
- if (ConvTemplate)
- S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
- Init, DeclType, CandidateSet);
- else
- S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
- DeclType, CandidateSet);
+ // If this is an explicit conversion, and we're not allowed to consider
+ // explicit conversions, skip it.
+ if (!AllowExplicit && Conv->isExplicit())
+ continue;
+
+ if (AllowRvalues) {
+ bool DerivedToBase = false;
+ bool ObjCConversion = false;
+ if (!ConvTemplate &&
+ S.CompareReferenceRelationship(DeclLoc,
+ Conv->getConversionType().getNonReferenceType().getUnqualifiedType(),
+ DeclType.getNonReferenceType().getUnqualifiedType(),
+ DerivedToBase, ObjCConversion)
+ == Sema::Ref_Incompatible)
+ continue;
+ } else {
+ // If the conversion function doesn't return a reference type,
+ // it can't be considered for this conversion. An rvalue reference
+ // is only acceptable if its referencee is a function type.
+
+ const ReferenceType *RefType =
+ Conv->getConversionType()->getAs<ReferenceType>();
+ if (!RefType ||
+ (!RefType->isLValueReferenceType() &&
+ !RefType->getPointeeType()->isFunctionType()))
+ continue;
}
+
+ if (ConvTemplate)
+ S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+ Init, ToType, CandidateSet);
+ else
+ S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+ ToType, CandidateSet);
}
OverloadCandidateSet::iterator Best;
- switch (S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+ switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
case OR_Success:
// C++ [over.ics.ref]p1:
//
@@ -2736,9 +2839,11 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// Compute some basic properties of the types and the initializer.
bool isRValRef = DeclType->isRValueReferenceType();
bool DerivedToBase = false;
+ bool ObjCConversion = false;
Expr::Classification InitCategory = Init->Classify(S.Context);
Sema::ReferenceCompareResult RefRelationship
- = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
+ = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase,
+ ObjCConversion);
// C++0x [dcl.init.ref]p5:
@@ -2764,7 +2869,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// derived-to-base Conversion (13.3.3.1).
ICS.setStandard();
ICS.Standard.First = ICK_Identity;
- ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
+ ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+ : ObjCConversion? ICK_Compatible_Conversion
+ : ICK_Identity;
ICS.Standard.Third = ICK_Identity;
ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
ICS.Standard.setToType(0, T2);
@@ -2792,8 +2899,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
if (!SuppressUserConversions && T2->isRecordType() &&
!S.RequireCompleteType(DeclLoc, T2, 0) &&
RefRelationship == Sema::Ref_Incompatible) {
- if (FindConversionToLValue(S, ICS, DeclType, DeclLoc,
- Init, T2, AllowExplicit))
+ if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+ Init, T2, /*AllowRvalues=*/false,
+ AllowExplicit))
return ICS;
}
}
@@ -2845,26 +2953,37 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// that is the result of the conversion in the second case
// (or, in either case, to the appropriate base class
// subobject of the object).
- //
- // We're only checking the first case here, which is a direct
- // binding in C++0x but not in C++03.
- if (InitCategory.isRValue() && T2->isRecordType() &&
- RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
- ICS.setStandard();
- ICS.Standard.First = ICK_Identity;
- ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
- ICS.Standard.Third = ICK_Identity;
- ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
- ICS.Standard.setToType(0, T2);
- ICS.Standard.setToType(1, T1);
- ICS.Standard.setToType(2, T1);
- ICS.Standard.ReferenceBinding = true;
- ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
- ICS.Standard.RRefBinding = isRValRef;
- ICS.Standard.CopyConstructor = 0;
- return ICS;
+ if (T2->isRecordType()) {
+ // First case: "cv1 T1" is reference-compatible with "cv2 T2". This is a
+ // direct binding in C++0x but not in C++03.
+ if (InitCategory.isRValue() &&
+ RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+ ICS.setStandard();
+ ICS.Standard.First = ICK_Identity;
+ ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+ : ObjCConversion? ICK_Compatible_Conversion
+ : ICK_Identity;
+ ICS.Standard.Third = ICK_Identity;
+ ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+ ICS.Standard.setToType(0, T2);
+ ICS.Standard.setToType(1, T1);
+ ICS.Standard.setToType(2, T1);
+ ICS.Standard.ReferenceBinding = true;
+ ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
+ ICS.Standard.RRefBinding = isRValRef;
+ ICS.Standard.CopyConstructor = 0;
+ return ICS;
+ }
+
+ // Second case: not reference-related.
+ if (RefRelationship == Sema::Ref_Incompatible &&
+ !S.RequireCompleteType(DeclLoc, T2, 0) &&
+ FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+ Init, T2, /*AllowRvalues=*/true,
+ AllowExplicit))
+ return ICS;
}
-
+
// -- Otherwise, a temporary of type "cv1 T1" is created and
// initialized from the initializer expression using the
// rules for a non-reference copy initialization (8.5). The
@@ -2899,9 +3018,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
// the argument expression. Any difference in top-level
// cv-qualification is subsumed by the initialization itself
// and does not constitute a conversion.
- ICS = S.TryImplicitConversion(Init, T1, SuppressUserConversions,
- /*AllowExplicit=*/false,
- /*InOverloadResolution=*/false);
+ ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions,
+ /*AllowExplicit=*/false,
+ /*InOverloadResolution=*/false);
// Of course, that's still a reference binding.
if (ICS.isStandard()) {
@@ -2930,25 +3049,25 @@ TryCopyInitialization(Sema &S, Expr *From, QualType ToType,
SuppressUserConversions,
/*AllowExplicit=*/false);
- return S.TryImplicitConversion(From, ToType,
- SuppressUserConversions,
- /*AllowExplicit=*/false,
- InOverloadResolution);
+ return TryImplicitConversion(S, From, ToType,
+ SuppressUserConversions,
+ /*AllowExplicit=*/false,
+ InOverloadResolution);
}
/// TryObjectArgumentInitialization - Try to initialize the object
/// parameter of the given member function (@c Method) from the
/// expression @p From.
-ImplicitConversionSequence
-Sema::TryObjectArgumentInitialization(QualType OrigFromType,
- CXXMethodDecl *Method,
- CXXRecordDecl *ActingContext) {
- QualType ClassType = Context.getTypeDeclType(ActingContext);
+static ImplicitConversionSequence
+TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
+ CXXMethodDecl *Method,
+ CXXRecordDecl *ActingContext) {
+ QualType ClassType = S.Context.getTypeDeclType(ActingContext);
// [class.dtor]p2: A destructor can be invoked for a const, volatile or
// const volatile object.
unsigned Quals = isa<CXXDestructorDecl>(Method) ?
Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers();
- QualType ImplicitParamType = Context.getCVRQualifiedType(ClassType, Quals);
+ QualType ImplicitParamType = S.Context.getCVRQualifiedType(ClassType, Quals);
// Set up the conversion sequence as a "bad" conversion, to allow us
// to exit early.
@@ -2972,7 +3091,7 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
// First check the qualifiers. We don't care about lvalue-vs-rvalue
// with the implicit object parameter (C++ [over.match.funcs]p5).
- QualType FromTypeCanon = Context.getCanonicalType(FromType);
+ QualType FromTypeCanon = S.Context.getCanonicalType(FromType);
if (ImplicitParamType.getCVRQualifiers()
!= FromTypeCanon.getLocalCVRQualifiers() &&
!ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) {
@@ -2983,11 +3102,11 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
// Check that we have either the same type or a derived type. It
// affects the conversion rank.
- QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
+ QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType);
ImplicitConversionKind SecondKind;
if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
SecondKind = ICK_Identity;
- } else if (IsDerivedFrom(FromType, ClassType))
+ } else if (S.IsDerivedFrom(FromType, ClassType))
SecondKind = ICK_Derived_To_Base;
else {
ICS.setBad(BadConversionSequence::unrelated_class,
@@ -3030,7 +3149,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
// Note that we always use the true parent context when performing
// the actual argument initialization.
ImplicitConversionSequence ICS
- = TryObjectArgumentInitialization(From->getType(), Method,
+ = TryObjectArgumentInitialization(*this, From->getType(), Method,
Method->getParent());
if (ICS.isBad())
return Diag(From->getSourceRange().getBegin(),
@@ -3041,16 +3160,17 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
if (!Context.hasSameType(From->getType(), DestType))
- ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
- /*isLvalue=*/!From->getType()->isPointerType());
+ ImpCastExprToType(From, DestType, CK_NoOp,
+ From->getType()->isPointerType() ? VK_RValue : VK_LValue);
return false;
}
/// TryContextuallyConvertToBool - Attempt to contextually convert the
/// expression From to bool (C++0x [conv]p3).
-ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
+static ImplicitConversionSequence
+TryContextuallyConvertToBool(Sema &S, Expr *From) {
// FIXME: This is pretty broken.
- return TryImplicitConversion(From, Context.BoolTy,
+ return TryImplicitConversion(S, From, S.Context.BoolTy,
// FIXME: Are these flags correct?
/*SuppressUserConversions=*/false,
/*AllowExplicit=*/true,
@@ -3060,7 +3180,7 @@ ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
/// PerformContextuallyConvertToBool - Perform a contextual conversion
/// of the expression From to bool (C++0x [conv]p3).
bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
- ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
+ ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
@@ -3073,20 +3193,21 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
/// TryContextuallyConvertToObjCId - Attempt to contextually convert the
/// expression From to 'id'.
-ImplicitConversionSequence Sema::TryContextuallyConvertToObjCId(Expr *From) {
- QualType Ty = Context.getObjCIdType();
- return TryImplicitConversion(From, Ty,
- // FIXME: Are these flags correct?
- /*SuppressUserConversions=*/false,
- /*AllowExplicit=*/true,
- /*InOverloadResolution=*/false);
+static ImplicitConversionSequence
+TryContextuallyConvertToObjCId(Sema &S, Expr *From) {
+ QualType Ty = S.Context.getObjCIdType();
+ return TryImplicitConversion(S, From, Ty,
+ // FIXME: Are these flags correct?
+ /*SuppressUserConversions=*/false,
+ /*AllowExplicit=*/true,
+ /*InOverloadResolution=*/false);
}
-
+
/// PerformContextuallyConvertToObjCId - Perform a contextual conversion
/// of the expression From to 'id'.
bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
QualType Ty = Context.getObjCIdType();
- ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(From);
+ ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Ty, ICS, AA_Converting);
return true;
@@ -3128,8 +3249,8 @@ bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
///
/// \returns The expression, converted to an integral or enumeration type if
/// successful.
-Sema::OwningExprResult
-Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
+ExprResult
+Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
const PartialDiagnostic &NotIntDiag,
const PartialDiagnostic &IncompleteDiag,
const PartialDiagnostic &ExplicitConvDiag,
@@ -3137,16 +3258,14 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
const PartialDiagnostic &AmbigDiag,
const PartialDiagnostic &AmbigNote,
const PartialDiagnostic &ConvDiag) {
- Expr *From = static_cast<Expr *>(FromE.get());
-
// We can't perform any more checking for type-dependent expressions.
if (From->isTypeDependent())
- return move(FromE);
+ return Owned(From);
// If the expression already has integral or enumeration type, we're golden.
QualType T = From->getType();
if (T->isIntegralOrEnumerationType())
- return move(FromE);
+ return Owned(From);
// FIXME: Check for missing '()' if T is a function type?
@@ -3156,12 +3275,12 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
if (!RecordTy || !getLangOptions().CPlusPlus) {
Diag(Loc, NotIntDiag)
<< T << From->getSourceRange();
- return move(FromE);
+ return Owned(From);
}
// We must have a complete class type.
if (RequireCompleteType(Loc, T, IncompleteDiag))
- return move(FromE);
+ return Owned(From);
// Look for a conversion to an integral or enumeration type.
UnresolvedSet<4> ViableConversions;
@@ -3213,8 +3332,7 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
return ExprError();
CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
- From = BuildCXXMemberCallExpr(FromE.takeAs<Expr>(), Found, Conversion);
- FromE = Owned(From);
+ From = BuildCXXMemberCallExpr(From, Found, Conversion);
}
// We'll complain below about a non-integral condition type.
@@ -3237,9 +3355,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
<< T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
}
- From = BuildCXXMemberCallExpr(FromE.takeAs<Expr>(), Found,
+ From = BuildCXXMemberCallExpr(From, Found,
cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
- FromE = Owned(From);
break;
}
@@ -3253,14 +3370,14 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
Diag(Conv->getLocation(), AmbigNote)
<< ConvTy->isEnumeralType() << ConvTy;
}
- return move(FromE);
+ return Owned(From);
}
if (!From->getType()->isIntegralOrEnumerationType())
Diag(Loc, NotIntDiag)
<< From->getType() << From->getSourceRange();
- return move(FromE);
+ return Owned(From);
}
/// AddOverloadCandidate - Adds the given function to the set of
@@ -3306,7 +3423,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
return;
// Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function)){
// C++ [class.copy]p3:
@@ -3469,7 +3586,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
return;
// Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
@@ -3513,7 +3630,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
// Determine the implicit conversion sequence for the object
// parameter.
Candidate.Conversions[0]
- = TryObjectArgumentInitialization(ObjectType, Method, ActingContext);
+ = TryObjectArgumentInitialization(*this, ObjectType, Method,
+ ActingContext);
if (Candidate.Conversions[0].isBad()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -3666,7 +3784,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
return;
// Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
@@ -3678,25 +3796,32 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Candidate.FinalConversion.setAsIdentityConversion();
Candidate.FinalConversion.setFromType(ConvType);
Candidate.FinalConversion.setAllToTypes(ToType);
+ Candidate.Viable = true;
+ Candidate.Conversions.resize(1);
+ // C++ [over.match.funcs]p4:
+ // For conversion functions, the function is considered to be a member of
+ // the class of the implicit implied object argument for the purpose of
+ // defining the type of the implicit object parameter.
+ //
// Determine the implicit conversion sequence for the implicit
// object parameter.
- Candidate.Viable = true;
- Candidate.Conversions.resize(1);
+ QualType ImplicitParamType = From->getType();
+ if (const PointerType *FromPtrType = ImplicitParamType->getAs<PointerType>())
+ ImplicitParamType = FromPtrType->getPointeeType();
+ CXXRecordDecl *ConversionContext
+ = cast<CXXRecordDecl>(ImplicitParamType->getAs<RecordType>()->getDecl());
+
Candidate.Conversions[0]
- = TryObjectArgumentInitialization(From->getType(), Conversion,
- ActingContext);
- // Conversion functions to a different type in the base class is visible in
- // the derived class. So, a derived to base conversion should not participate
- // in overload resolution.
- if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
- Candidate.Conversions[0].Standard.Second = ICK_Identity;
+ = TryObjectArgumentInitialization(*this, From->getType(), Conversion,
+ ConversionContext);
+
if (Candidate.Conversions[0].isBad()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_conversion;
return;
}
-
+
// We won't go through a user-define type conversion function to convert a
// derived to base as such conversions are given Conversion Rank. They only
// go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user]
@@ -3719,9 +3844,10 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
// well-formed.
DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
From->getLocStart());
- ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
- CastExpr::CK_FunctionToPointerDecay,
- &ConversionRef, CXXBaseSpecifierArray(), false);
+ ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
+ Context.getPointerType(Conversion->getType()),
+ CK_FunctionToPointerDecay,
+ &ConversionRef, VK_RValue);
// Note that it is safe to allocate CallExpr on the stack here because
// there are 0 arguments (i.e., nothing is allocated using ASTContext's
@@ -3819,7 +3945,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
return;
// Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -3834,7 +3960,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// Determine the implicit conversion sequence for the implicit
// object parameter.
ImplicitConversionSequence ObjectInit
- = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext);
+ = TryObjectArgumentInitialization(*this, ObjectType, Conversion,
+ ActingContext);
if (ObjectInit.isBad()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -3925,9 +4052,6 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// candidates, non-member candidates and built-in candidates, are
// constructed as follows:
QualType T1 = Args[0]->getType();
- QualType T2;
- if (NumArgs > 1)
- T2 = Args[1]->getType();
// -- If T1 is a class type, the set of member candidates is the
// result of the qualified lookup of T1::operator@
@@ -3966,7 +4090,7 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
bool IsAssignmentOperator,
unsigned NumContextualBoolArguments) {
// Overload resolution is always an unevaluated context.
- EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
@@ -3999,7 +4123,8 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
if (ArgIdx < NumContextualBoolArguments) {
assert(ParamTys[ArgIdx] == Context.BoolTy &&
"Contextual conversion to bool requires bool type");
- Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(Args[ArgIdx]);
+ Candidate.Conversions[ArgIdx]
+ = TryContextuallyConvertToBool(*this, Args[ArgIdx]);
} else {
Candidate.Conversions[ArgIdx]
= TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx],
@@ -4100,11 +4225,21 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
// Insert this type.
if (!PointerTypes.insert(Ty))
return false;
-
+
+ QualType PointeeTy;
const PointerType *PointerTy = Ty->getAs<PointerType>();
- assert(PointerTy && "type was not a pointer type!");
-
- QualType PointeeTy = PointerTy->getPointeeType();
+ bool buildObjCPtr = false;
+ if (!PointerTy) {
+ if (const ObjCObjectPointerType *PTy = Ty->getAs<ObjCObjectPointerType>()) {
+ PointeeTy = PTy->getPointeeType();
+ buildObjCPtr = true;
+ }
+ else
+ assert(false && "type was not a pointer type!");
+ }
+ else
+ PointeeTy = PointerTy->getPointeeType();
+
// Don't add qualified variants of arrays. For one, they're not allowed
// (the qualifier would sink to the element type), and for another, the
// only overload situation where it matters is subscript or pointer +- int,
@@ -4125,7 +4260,10 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue;
if ((CVR & Qualifiers::Restrict) && !hasRestrict) continue;
QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
- PointerTypes.insert(Context.getPointerType(QPointeeTy));
+ if (!buildObjCPtr)
+ PointerTypes.insert(Context.getPointerType(QPointeeTy));
+ else
+ PointerTypes.insert(Context.getObjCObjectPointerType(QPointeeTy));
}
return true;
@@ -4200,10 +4338,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
// If we're dealing with an array type, decay to the pointer.
if (Ty->isArrayType())
Ty = SemaRef.Context.getArrayDecayedType(Ty);
-
- if (const PointerType *PointerTy = Ty->getAs<PointerType>()) {
- QualType PointeeTy = PointerTy->getPointeeType();
-
+ if (Ty->isObjCIdType() || Ty->isObjCClassType())
+ PointerTypes.insert(Ty);
+ else if (Ty->getAs<PointerType>() || Ty->getAs<ObjCObjectPointerType>()) {
// Insert our type, and its more-qualified variants, into the set
// of types.
if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
@@ -4479,7 +4616,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
// Skip pointer types that aren't pointers to object types.
- if (!(*Ptr)->getAs<PointerType>()->getPointeeType()->isObjectType())
+ if (!(*Ptr)->getPointeeType()->isIncompleteOrObjectType())
continue;
QualType ParamTypes[2] = {
@@ -4519,7 +4656,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType ParamTy = *Ptr;
- QualType PointeeTy = ParamTy->getAs<PointerType>()->getPointeeType();
+ QualType PointeeTy = ParamTy->getPointeeType();
AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
&ParamTy, Args, 1, CandidateSet);
}
@@ -5000,7 +5137,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
- QualType PointeeType = (*Ptr)->getAs<PointerType>()->getPointeeType();
+ QualType PointeeType = (*Ptr)->getPointeeType();
QualType ResultTy = Context.getLValueReferenceType(PointeeType);
// T& operator[](T*, ptrdiff_t)
@@ -5028,18 +5165,16 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
QualType C1Ty = (*Ptr);
QualType C1;
QualifierCollector Q1;
- if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
- C1 = QualType(Q1.strip(PointerTy->getPointeeType()), 0);
- if (!isa<RecordType>(C1))
- continue;
- // heuristic to reduce number of builtin candidates in the set.
- // Add volatile/restrict version only if there are conversions to a
- // volatile/restrict type.
- if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile())
- continue;
- if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict())
- continue;
- }
+ C1 = QualType(Q1.strip(C1Ty->getPointeeType()), 0);
+ if (!isa<RecordType>(C1))
+ continue;
+ // heuristic to reduce number of builtin candidates in the set.
+ // Add volatile/restrict version only if there are conversions to a
+ // volatile/restrict type.
+ if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile())
+ continue;
+ if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict())
+ continue;
for (BuiltinCandidateTypeSet::iterator
MemPtr = CandidateTypes.member_pointer_begin(),
MemPtrEnd = CandidateTypes.member_pointer_end();
@@ -5148,9 +5283,10 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
/// isBetterOverloadCandidate - Determines whether the first overload
/// candidate is a better candidate than the second (C++ 13.3.3p1).
bool
-Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2,
- SourceLocation Loc) {
+isBetterOverloadCandidate(Sema &S,
+ const OverloadCandidate& Cand1,
+ const OverloadCandidate& Cand2,
+ SourceLocation Loc) {
// Define viable functions to be better candidates than non-viable
// functions.
if (!Cand2.Viable)
@@ -5176,7 +5312,8 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
bool HasBetterConversion = false;
for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
- switch (CompareImplicitConversionSequences(Cand1.Conversions[ArgIdx],
+ switch (CompareImplicitConversionSequences(S,
+ Cand1.Conversions[ArgIdx],
Cand2.Conversions[ArgIdx])) {
case ImplicitConversionSequence::Better:
// Cand1 has a better conversion sequence.
@@ -5211,9 +5348,9 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
Cand2.Function && Cand2.Function->getPrimaryTemplate())
if (FunctionTemplateDecl *BetterTemplate
- = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
- Cand2.Function->getPrimaryTemplate(),
- Loc,
+ = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+ Cand2.Function->getPrimaryTemplate(),
+ Loc,
isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
: TPOC_Call))
return BetterTemplate == Cand1.Function->getPrimaryTemplate();
@@ -5227,7 +5364,8 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
if (Cand1.Function && Cand2.Function &&
isa<CXXConversionDecl>(Cand1.Function) &&
isa<CXXConversionDecl>(Cand2.Function)) {
- switch (CompareStandardConversionSequences(Cand1.FinalConversion,
+ switch (CompareStandardConversionSequences(S,
+ Cand1.FinalConversion,
Cand2.FinalConversion)) {
case ImplicitConversionSequence::Better:
// Cand1 has a better conversion sequence.
@@ -5258,32 +5396,28 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
/// function, Best points to the candidate function found.
///
/// \returns The result of overload resolution.
-OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
- SourceLocation Loc,
- OverloadCandidateSet::iterator& Best) {
+OverloadingResult
+OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
+ iterator& Best) {
// Find the best viable function.
- Best = CandidateSet.end();
- for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
- Cand != CandidateSet.end(); ++Cand) {
- if (Cand->Viable) {
- if (Best == CandidateSet.end() ||
- isBetterOverloadCandidate(*Cand, *Best, Loc))
+ Best = end();
+ for (iterator Cand = begin(); Cand != end(); ++Cand) {
+ if (Cand->Viable)
+ if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc))
Best = Cand;
- }
}
// If we didn't find any viable functions, abort.
- if (Best == CandidateSet.end())
+ if (Best == end())
return OR_No_Viable_Function;
// Make sure that this function is better than every other viable
// function. If not, we have an ambiguity.
- for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
- Cand != CandidateSet.end(); ++Cand) {
+ for (iterator Cand = begin(); Cand != end(); ++Cand) {
if (Cand->Viable &&
Cand != Best &&
- !isBetterOverloadCandidate(*Best, *Cand, Loc)) {
- Best = CandidateSet.end();
+ !isBetterOverloadCandidate(S, *Best, *Cand, Loc)) {
+ Best = end();
return OR_Ambiguous;
}
}
@@ -5301,7 +5435,7 @@ OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
// (clause 13), user-defined conversions (12.3.2), allocation function for
// placement new (5.3.4), as well as non-default initialization (8.5).
if (Best->Function)
- MarkDeclarationReferenced(Loc, Best->Function);
+ S.MarkDeclarationReferenced(Loc, Best->Function);
return OR_Success;
}
@@ -5365,14 +5499,15 @@ void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
/// Diagnoses an ambiguous conversion. The partial diagnostic is the
/// "lead" diagnostic; it will be given two arguments, the source and
/// target types of the conversion.
-void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
- SourceLocation CaretLoc,
- const PartialDiagnostic &PDiag) {
- Diag(CaretLoc, PDiag)
- << ICS.Ambiguous.getFromType() << ICS.Ambiguous.getToType();
+void ImplicitConversionSequence::DiagnoseAmbiguousConversion(
+ Sema &S,
+ SourceLocation CaretLoc,
+ const PartialDiagnostic &PDiag) const {
+ S.Diag(CaretLoc, PDiag)
+ << Ambiguous.getFromType() << Ambiguous.getToType();
for (AmbiguousConversionSequence::const_iterator
- I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) {
- NoteOverloadCandidate(*I);
+ I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) {
+ S.NoteOverloadCandidate(*I);
}
}
@@ -5589,8 +5724,31 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
return;
}
- case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals: {
+ case Sema::TDK_Underqualified: {
+ assert(ParamD && "no parameter found for bad qualifiers deduction result");
+ TemplateTypeParmDecl *TParam = cast<TemplateTypeParmDecl>(ParamD);
+
+ QualType Param = Cand->DeductionFailure.getFirstArg()->getAsType();
+
+ // Param will have been canonicalized, but it should just be a
+ // qualified version of ParamD, so move the qualifiers to that.
+ QualifierCollector Qs(S.Context);
+ Qs.strip(Param);
+ QualType NonCanonParam = Qs.apply(TParam->getTypeForDecl());
+ assert(S.Context.hasSameType(Param, NonCanonParam));
+
+ // Arg has also been canonicalized, but there's nothing we can do
+ // about that. It also doesn't matter as much, because it won't
+ // have any template parameters in it (because deduction isn't
+ // done on dependent types).
+ QualType Arg = Cand->DeductionFailure.getSecondArg()->getAsType();
+
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_underqualified)
+ << ParamD->getDeclName() << Arg << NonCanonParam;
+ return;
+ }
+
+ case Sema::TDK_Inconsistent: {
assert(ParamD && "no parameter found for inconsistent deduction result");
int which = 0;
if (isa<TemplateTypeParmDecl>(ParamD))
@@ -5779,7 +5937,7 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
if (ICS.isBad()) break; // all meaningless after first invalid
if (!ICS.isAmbiguous()) continue;
- S.DiagnoseAmbiguousConversion(ICS, OpLoc,
+ ICS.DiagnoseAmbiguousConversion(S, OpLoc,
S.PDiag(diag::note_ambiguous_type_conversion));
}
}
@@ -5808,8 +5966,8 @@ struct CompareOverloadCandidatesForDisplay {
// TODO: introduce a tri-valued comparison for overload
// candidates. Would be more worthwhile if we had a sort
// that could exploit it.
- if (S.isBetterOverloadCandidate(*L, *R, SourceLocation())) return true;
- if (S.isBetterOverloadCandidate(*R, *L, SourceLocation())) return false;
+ if (isBetterOverloadCandidate(S, *L, *R, SourceLocation())) return true;
+ if (isBetterOverloadCandidate(S, *R, *L, SourceLocation())) return false;
} else if (R->Viable)
return false;
@@ -5838,8 +5996,9 @@ struct CompareOverloadCandidatesForDisplay {
int leftBetter = 0;
unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
for (unsigned E = L->Conversions.size(); I != E; ++I) {
- switch (S.CompareImplicitConversionSequences(L->Conversions[I],
- R->Conversions[I])) {
+ switch (CompareImplicitConversionSequences(S,
+ L->Conversions[I],
+ R->Conversions[I])) {
case ImplicitConversionSequence::Better:
leftBetter++;
break;
@@ -5947,23 +6106,20 @@ void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
/// PrintOverloadCandidates - When overload resolution fails, prints
/// diagnostic messages containing the candidates in the candidate
/// set.
-void
-Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
- OverloadCandidateDisplayKind OCD,
- Expr **Args, unsigned NumArgs,
- const char *Opc,
- SourceLocation OpLoc) {
+void OverloadCandidateSet::NoteCandidates(Sema &S,
+ OverloadCandidateDisplayKind OCD,
+ Expr **Args, unsigned NumArgs,
+ const char *Opc,
+ SourceLocation OpLoc) {
// Sort the candidates by viability and position. Sorting directly would
// be prohibitive, so we make a set of pointers and sort those.
llvm::SmallVector<OverloadCandidate*, 32> Cands;
- if (OCD == OCD_AllCandidates) Cands.reserve(CandidateSet.size());
- for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
- LastCand = CandidateSet.end();
- Cand != LastCand; ++Cand) {
+ if (OCD == OCD_AllCandidates) Cands.reserve(size());
+ for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) {
if (Cand->Viable)
Cands.push_back(Cand);
else if (OCD == OCD_AllCandidates) {
- CompleteNonViableCandidate(*this, Cand, Args, NumArgs);
+ CompleteNonViableCandidate(S, Cand, Args, NumArgs);
if (Cand->Function || Cand->IsSurrogate)
Cands.push_back(Cand);
// Otherwise, this a non-viable builtin candidate. We do not, in general,
@@ -5972,12 +6128,12 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
}
std::sort(Cands.begin(), Cands.end(),
- CompareOverloadCandidatesForDisplay(*this));
+ CompareOverloadCandidatesForDisplay(S));
bool ReportedAmbiguousConversions = false;
llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
- const Diagnostic::OverloadsShown ShowOverloads = Diags.getShowOverloads();
+ const Diagnostic::OverloadsShown ShowOverloads = S.Diags.getShowOverloads();
unsigned CandsShown = 0;
for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
OverloadCandidate *Cand = *I;
@@ -5991,9 +6147,9 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
++CandsShown;
if (Cand->Function)
- NoteFunctionCandidate(*this, Cand, Args, NumArgs);
+ NoteFunctionCandidate(S, Cand, Args, NumArgs);
else if (Cand->IsSurrogate)
- NoteSurrogateCandidate(*this, Cand);
+ NoteSurrogateCandidate(S, Cand);
else {
assert(Cand->Viable &&
"Non-viable built-in candidates are not added to Cands.");
@@ -6004,17 +6160,17 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
// FIXME: It's quite possible for different conversions to see
// different ambiguities, though.
if (!ReportedAmbiguousConversions) {
- NoteAmbiguousUserConversions(*this, OpLoc, Cand);
+ NoteAmbiguousUserConversions(S, OpLoc, Cand);
ReportedAmbiguousConversions = true;
}
// If this is a viable builtin, print it.
- NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
+ NoteBuiltinOperatorCandidate(S, Opc, OpLoc, Cand);
}
}
if (I != E)
- Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
+ S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
}
static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {
@@ -6061,12 +6217,13 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
// C++ [over.over]p1:
// [...] The overloaded function name can be preceded by the &
// operator.
- OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
- TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
- if (OvlExpr->hasExplicitTemplateArgs()) {
- OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
- ExplicitTemplateArgs = &ETABuffer;
- }
+ // However, remember whether the expression has member-pointer form:
+ // C++ [expr.unary.op]p4:
+ // A pointer to member is only formed when an explicit & is used
+ // and its operand is a qualified-id not enclosed in
+ // parentheses.
+ OverloadExpr::FindResult Ovl = OverloadExpr::find(From);
+ OverloadExpr *OvlExpr = Ovl.Expression;
// We expect a pointer or reference to function, or a function pointer.
FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
@@ -6078,6 +6235,25 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
return 0;
}
+ // If the overload expression doesn't have the form of a pointer to
+ // member, don't try to convert it to a pointer-to-member type.
+ if (IsMember && !Ovl.HasFormOfMemberPointer) {
+ if (!Complain) return 0;
+
+ // TODO: Should we condition this on whether any functions might
+ // have matched, or is it more appropriate to do that in callers?
+ // TODO: a fixit wouldn't hurt.
+ Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier)
+ << ToType << OvlExpr->getSourceRange();
+ return 0;
+ }
+
+ TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+ if (OvlExpr->hasExplicitTemplateArgs()) {
+ OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+ ExplicitTemplateArgs = &ETABuffer;
+ }
+
assert(From->getType() == Context.OverloadTy);
// Look through all of the overloaded functions, searching for one
@@ -6267,7 +6443,7 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
if (From->getType() != Context.OverloadTy)
return 0;
- OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+ OverloadExpr *OvlExpr = OverloadExpr::find(From).Expression;
// If we didn't actually find any template-ids, we're done.
if (!OvlExpr->hasExplicitTemplateArgs())
@@ -6405,18 +6581,10 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
PartialOverloading);
}
-static Sema::OwningExprResult Destroy(Sema &SemaRef, Expr *Fn,
- Expr **Args, unsigned NumArgs) {
- Fn->Destroy(SemaRef.Context);
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
- Args[Arg]->Destroy(SemaRef.Context);
- return SemaRef.ExprError();
-}
-
/// Attempts to recover from a call where no functions were found.
///
/// Returns true if new candidates were found.
-static Sema::OwningExprResult
+static ExprResult
BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
UnresolvedLookupExpr *ULE,
SourceLocation LParenLoc,
@@ -6440,13 +6608,13 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
Sema::LookupOrdinaryName);
if (SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression))
- return Destroy(SemaRef, Fn, Args, NumArgs);
+ return ExprError();
assert(!R.empty() && "lookup results empty despite recovery");
// Build an implicit member call if appropriate. Just drop the
// casts and such from the call, we don't really care.
- Sema::OwningExprResult NewFn = SemaRef.ExprError();
+ ExprResult NewFn = ExprError();
if ((*R.begin())->isCXXClassMember())
NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, R, ExplicitTemplateArgs);
else if (ExplicitTemplateArgs)
@@ -6455,15 +6623,13 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false);
if (NewFn.isInvalid())
- return Destroy(SemaRef, Fn, Args, NumArgs);
-
- Fn->Destroy(SemaRef.Context);
+ return ExprError();
// This shouldn't cause an infinite loop because we're giving it
// an expression with non-empty lookup results, which should never
// end up here.
- return SemaRef.ActOnCallExpr(/*Scope*/ 0, move(NewFn), LParenLoc,
- Sema::MultiExprArg(SemaRef, (void**) Args, NumArgs),
+ return SemaRef.ActOnCallExpr(/*Scope*/ 0, NewFn.take(), LParenLoc,
+ MultiExprArg(Args, NumArgs),
CommaLocs, RParenLoc);
}
@@ -6474,7 +6640,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
/// the function declaration produced by overload
/// resolution. Otherwise, emits diagnostics, deletes all of the
/// arguments and Fn, and returns NULL.
-Sema::OwningExprResult
+ExprResult
Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
@@ -6512,7 +6678,7 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
CommaLocs, RParenLoc);
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
+ switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
case OR_Success: {
FunctionDecl *FDecl = Best->Function;
CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
@@ -6525,13 +6691,13 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
Diag(Fn->getSourceRange().getBegin(),
diag::err_ovl_no_viable_function_in_call)
<< ULE->getName() << Fn->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Ambiguous:
Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call)
<< ULE->getName() << Fn->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_Deleted:
@@ -6539,15 +6705,11 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
<< Best->Function->isDeleted()
<< ULE->getName()
<< Fn->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
}
- // Overload resolution failed. Destroy all of the subexpressions and
- // return NULL.
- Fn->Destroy(Context);
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
- Args[Arg]->Destroy(Context);
+ // Overload resolution failed.
return ExprError();
}
@@ -6572,16 +6734,17 @@ static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
/// by CreateOverloadedUnaryOp().
///
/// \param input The input argument.
-Sema::OwningExprResult
+ExprResult
Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
const UnresolvedSetImpl &Fns,
- ExprArg input) {
+ Expr *Input) {
UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
- Expr *Input = (Expr *)input.get();
OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc);
assert(Op != OO_None && "Invalid opcode for overloaded unary operator");
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+ // TODO: provide better source location info.
+ DeclarationNameInfo OpNameInfo(OpName, OpLoc);
Expr *Args[2] = { Input, 0 };
unsigned NumArgs = 1;
@@ -6589,16 +6752,16 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// For post-increment and post-decrement, add the implicit '0' as
// the second argument, so that we know this is a post-increment or
// post-decrement.
- if (Opc == UnaryOperator::PostInc || Opc == UnaryOperator::PostDec) {
+ if (Opc == UO_PostInc || Opc == UO_PostDec) {
llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
- Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
- SourceLocation());
+ Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy,
+ SourceLocation());
NumArgs = 2;
}
if (Input->isTypeDependent()) {
if (Fns.empty())
- return Owned(new (Context) UnaryOperator(input.takeAs<Expr>(),
+ return Owned(new (Context) UnaryOperator(Input,
Opc,
Context.DependentTy,
OpLoc));
@@ -6606,10 +6769,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
- 0, SourceRange(), OpName, OpLoc,
+ 0, SourceRange(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
- input.release();
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
&Args[0], NumArgs,
Context.DependentTy,
@@ -6636,7 +6798,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+ switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
@@ -6654,16 +6816,14 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
return ExprError();
} else {
// Convert the arguments.
- OwningExprResult InputInit
+ ExprResult InputInit
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(0)),
SourceLocation(),
- move(input));
+ Input);
if (InputInit.isInvalid())
return ExprError();
-
- input = move(InputInit);
- Input = (Expr *)input.get();
+ Input = InputInit.take();
}
DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
@@ -6676,17 +6836,16 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
SourceLocation());
UsualUnaryConversions(FnExpr);
- input.release();
Args[0] = Input;
- ExprOwningPtr<CallExpr> TheCall(this,
+ CallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
- Args, NumArgs, ResultTy, OpLoc));
+ Args, NumArgs, ResultTy, OpLoc);
- if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(),
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
FnDecl))
return ExprError();
- return MaybeBindToTemporary(TheCall.release());
+ return MaybeBindToTemporary(TheCall);
} else {
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
@@ -6708,8 +6867,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs,
- UnaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
+ Args, NumArgs,
+ UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
@@ -6717,15 +6877,14 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
<< Best->Function->isDeleted()
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return ExprError();
}
// Either we found no viable overloaded operator or we matched a
// built-in operator. In either case, fall through to trying to
// build a built-in operation.
- input.release();
- return CreateBuiltinUnaryOp(OpLoc, Opc, Owned(Input));
+ return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
}
/// \brief Create a binary operation that may resolve to an overloaded
@@ -6745,7 +6904,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
///
/// \param LHS Left-hand argument.
/// \param RHS Right-hand argument.
-Sema::OwningExprResult
+ExprResult
Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
unsigned OpcIn,
const UnresolvedSetImpl &Fns,
@@ -6763,7 +6922,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Fns.empty()) {
// If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
- if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
+ if (Opc <= BO_Assign || Opc > BO_OrAssign)
return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
Context.DependentTy, OpLoc));
@@ -6776,9 +6935,11 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// FIXME: save results of ADL from here?
CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+ // TODO: provide better source location info in DNLoc component.
+ DeclarationNameInfo OpNameInfo(OpName, OpLoc);
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
- 0, SourceRange(), OpName, OpLoc,
+ 0, SourceRange(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
@@ -6789,7 +6950,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// If this is the .* operator, which is not overloadable, just
// create a built-in binary operator.
- if (Opc == BinaryOperator::PtrMemD)
+ if (Opc == BO_PtrMemD)
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// If this is the assignment operator, we only perform overload resolution
@@ -6798,7 +6959,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// various built-in candidates, but as DR507 points out, this can lead to
// problems. So we do it this way, which pretty much follows what GCC does.
// Note that we go the traditional code path for compound assignment forms.
- if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
+ if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// Build an empty overload set.
@@ -6821,7 +6982,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+ switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
@@ -6835,7 +6996,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Best->Access is only meaningful for class members.
CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
- OwningExprResult Arg1
+ ExprResult Arg1
= PerformCopyInitialization(
InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(0)),
@@ -6851,7 +7012,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
Args[1] = RHS = Arg1.takeAs<Expr>();
} else {
// Convert the arguments.
- OwningExprResult Arg0
+ ExprResult Arg0
= PerformCopyInitialization(
InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(0)),
@@ -6860,7 +7021,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Arg0.isInvalid())
return ExprError();
- OwningExprResult Arg1
+ ExprResult Arg1
= PerformCopyInitialization(
InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(1)),
@@ -6884,16 +7045,15 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
OpLoc);
UsualUnaryConversions(FnExpr);
- ExprOwningPtr<CXXOperatorCallExpr>
- TheCall(this, new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
- Args, 2, ResultTy,
- OpLoc));
+ CXXOperatorCallExpr *TheCall =
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+ Args, 2, ResultTy, OpLoc);
- if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(),
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
FnDecl))
return ExprError();
- return MaybeBindToTemporary(TheCall.release());
+ return MaybeBindToTemporary(TheCall);
} else {
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
@@ -6913,15 +7073,15 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// If the operator is the operator , [...] and there are no
// viable functions, then the operator is assumed to be the
// built-in operator and interpreted according to clause 5.
- if (Opc == BinaryOperator::Comma)
+ if (Opc == BO_Comma)
break;
// For class as left operand for assignment or compound assigment operator
// do not fall through to handling in built-in, but report that no overloaded
// assignment operator found
- OwningExprResult Result = ExprError();
+ ExprResult Result = ExprError();
if (Args[0]->getType()->isRecordType() &&
- Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+ Opc >= BO_Assign && Opc <= BO_OrAssign) {
Diag(OpLoc, diag::err_ovl_no_viable_oper)
<< BinaryOperator::getOpcodeStr(Opc)
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
@@ -6933,8 +7093,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
assert(Result.isInvalid() &&
"C++ binary operator overloading is missing candidates!");
if (Result.isInvalid())
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
- BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
return move(Result);
}
@@ -6942,8 +7102,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< BinaryOperator::getOpcodeStr(Opc)
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
- BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
@@ -6951,7 +7111,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
<< Best->Function->isDeleted()
<< BinaryOperator::getOpcodeStr(Opc)
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2);
return ExprError();
}
@@ -6959,12 +7119,11 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
-Action::OwningExprResult
+ExprResult
Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
SourceLocation RLoc,
- ExprArg Base, ExprArg Idx) {
- Expr *Args[2] = { static_cast<Expr*>(Base.get()),
- static_cast<Expr*>(Idx.get()) };
+ Expr *Base, Expr *Idx) {
+ Expr *Args[2] = { Base, Idx };
DeclarationName OpName =
Context.DeclarationNames.getCXXOperatorName(OO_Subscript);
@@ -6973,16 +7132,17 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+ // CHECKME: no 'operator' keyword?
+ DeclarationNameInfo OpNameInfo(OpName, LLoc);
+ OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
- 0, SourceRange(), OpName, LLoc,
+ 0, SourceRange(), OpNameInfo,
/*ADL*/ true, /*Overloaded*/ false,
UnresolvedSetIterator(),
UnresolvedSetIterator());
// Can't add any actual overloads yet
- Base.release();
- Idx.release();
return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
Args, 2,
Context.DependentTy,
@@ -7002,7 +7162,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, LLoc, Best)) {
+ switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) {
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
@@ -7021,7 +7181,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
return ExprError();
// Convert the arguments.
- OwningExprResult InputInit
+ ExprResult InputInit
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(0)),
SourceLocation(),
@@ -7041,18 +7201,16 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
LLoc);
UsualUnaryConversions(FnExpr);
- Base.release();
- Idx.release();
- ExprOwningPtr<CXXOperatorCallExpr>
- TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
- FnExpr, Args, 2,
- ResultTy, RLoc));
+ CXXOperatorCallExpr *TheCall =
+ new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
+ FnExpr, Args, 2,
+ ResultTy, RLoc);
- if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall.get(),
+ if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
FnDecl))
return ExprError();
- return MaybeBindToTemporary(TheCall.release());
+ return MaybeBindToTemporary(TheCall);
} else {
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
@@ -7076,32 +7234,29 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
Diag(LLoc, diag::err_ovl_no_viable_subscript)
<< Args[0]->getType()
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
- "[]", LLoc);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+ "[]", LLoc);
return ExprError();
}
case OR_Ambiguous:
Diag(LLoc, diag::err_ovl_ambiguous_oper)
<< "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
- "[]", LLoc);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
+ "[]", LLoc);
return ExprError();
case OR_Deleted:
Diag(LLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted() << "[]"
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
- "[]", LLoc);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+ "[]", LLoc);
return ExprError();
}
// We matched a built-in operator; build it.
- Base.release();
- Idx.release();
- return CreateBuiltinArraySubscriptExpr(Owned(Args[0]), LLoc,
- Owned(Args[1]), RLoc);
+ return CreateBuiltinArraySubscriptExpr(Args[0], LLoc, Args[1], RLoc);
}
/// BuildCallToMemberFunction - Build a call to a member
@@ -7111,7 +7266,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
/// parameter). The caller needs to validate that the member
/// expression refers to a member function or an overloaded member
/// function.
-Sema::OwningExprResult
+ExprResult
Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
SourceLocation LParenLoc, Expr **Args,
unsigned NumArgs, SourceLocation *CommaLocs,
@@ -7174,7 +7329,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
DeclarationName DeclName = UnresExpr->getMemberName();
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) {
+ switch (CandidateSet.BestViableFunction(*this, UnresExpr->getLocStart(),
+ Best)) {
case OR_Success:
Method = cast<CXXMethodDecl>(Best->Function);
FoundDecl = Best->FoundDecl;
@@ -7186,14 +7342,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
Diag(UnresExpr->getMemberLoc(),
diag::err_ovl_no_viable_member_function_in_call)
<< DeclName << MemExprE->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
// FIXME: Leaking incoming expressions!
return ExprError();
case OR_Ambiguous:
Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call)
<< DeclName << MemExprE->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
// FIXME: Leaking incoming expressions!
return ExprError();
@@ -7201,7 +7357,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
<< Best->Function->isDeleted()
<< DeclName << MemExprE->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
// FIXME: Leaking incoming expressions!
return ExprError();
}
@@ -7219,15 +7375,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
}
assert(Method && "Member call to something that isn't a method?");
- ExprOwningPtr<CXXMemberCallExpr>
- TheCall(this, new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
- NumArgs,
- Method->getCallResultType(),
- RParenLoc));
+ CXXMemberCallExpr *TheCall =
+ new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs,
+ Method->getCallResultType(),
+ RParenLoc);
// Check for a valid return type.
if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(),
- TheCall.get(), Method))
+ TheCall, Method))
return ExprError();
// Convert the object argument (for a non-static member function call).
@@ -7242,21 +7397,21 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Convert the rest of the arguments
const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
- if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
+ if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, NumArgs,
RParenLoc))
return ExprError();
- if (CheckFunctionCall(Method, TheCall.get()))
+ if (CheckFunctionCall(Method, TheCall))
return ExprError();
- return MaybeBindToTemporary(TheCall.release());
+ return MaybeBindToTemporary(TheCall);
}
/// BuildCallToObjectOfClassType - Build a call to an object of class
/// type (C++ [over.call.object]), which can end up invoking an
/// overloaded function call operator (@c operator()) or performing a
/// user-defined conversion on the object argument.
-Sema::ExprResult
+ExprResult
Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
@@ -7338,7 +7493,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, Object->getLocStart(), Best)) {
+ switch (CandidateSet.BestViableFunction(*this, Object->getLocStart(),
+ Best)) {
case OR_Success:
// Overload resolution succeeded; we'll build the appropriate call
// below.
@@ -7353,14 +7509,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
Diag(Object->getSourceRange().getBegin(),
diag::err_ovl_no_viable_object_call)
<< Object->getType() << Object->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Ambiguous:
Diag(Object->getSourceRange().getBegin(),
diag::err_ovl_ambiguous_object_call)
<< Object->getType() << Object->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_Deleted:
@@ -7368,18 +7524,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
diag::err_ovl_deleted_object_call)
<< Best->Function->isDeleted()
<< Object->getType() << Object->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
}
- if (Best == CandidateSet.end()) {
- // We had an error; delete all of the subexpressions and return
- // the error.
- Object->Destroy(Context);
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
- Args[ArgIdx]->Destroy(Context);
+ if (Best == CandidateSet.end())
return true;
- }
if (Best->Function == 0) {
// Since there is no function declaration, this is one of the
@@ -7400,9 +7550,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl,
Conv);
- return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc,
- MultiExprArg(*this, (ExprTy**)Args, NumArgs),
- CommaLocs, RParenLoc).result();
+ return ActOnCallExpr(S, CE, LParenLoc, MultiExprArg(Args, NumArgs),
+ CommaLocs, RParenLoc);
}
CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
@@ -7438,13 +7587,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Once we've built TheCall, all of the expressions are properly
// owned.
QualType ResultTy = Method->getCallResultType();
- ExprOwningPtr<CXXOperatorCallExpr>
- TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
- MethodArgs, NumArgs + 1,
- ResultTy, RParenLoc));
+ CXXOperatorCallExpr *TheCall =
+ new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+ MethodArgs, NumArgs + 1,
+ ResultTy, RParenLoc);
delete [] MethodArgs;
- if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall.get(),
+ if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall,
Method))
return true;
@@ -7471,15 +7620,15 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Pass the argument.
- OwningExprResult InputInit
+ ExprResult InputInit
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
Method->getParamDecl(i)),
- SourceLocation(), Owned(Arg));
+ SourceLocation(), Arg);
IsError |= InputInit.isInvalid();
Arg = InputInit.takeAs<Expr>();
} else {
- OwningExprResult DefArg
+ ExprResult DefArg
= BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
if (DefArg.isInvalid()) {
IsError = true;
@@ -7504,18 +7653,17 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (IsError) return true;
- if (CheckFunctionCall(Method, TheCall.get()))
+ if (CheckFunctionCall(Method, TheCall))
return true;
- return MaybeBindToTemporary(TheCall.release()).result();
+ return MaybeBindToTemporary(TheCall);
}
/// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator->
/// (if one exists), where @c Base is an expression of class type and
/// @c Member is the name of the member we're trying to find.
-Sema::OwningExprResult
-Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
- Expr *Base = static_cast<Expr *>(BaseIn.get());
+ExprResult
+Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
assert(Base->getType()->isRecordType() && "left-hand side must have class type");
SourceLocation Loc = Base->getExprLoc();
@@ -7547,7 +7695,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+ switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
case OR_Success:
// Overload resolution succeeded; we'll build the call below.
break;
@@ -7559,20 +7707,20 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
else
Diag(OpLoc, diag::err_ovl_no_viable_oper)
<< "operator->" << Base->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
return ExprError();
case OR_Ambiguous:
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< "->" << Base->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Base, 1);
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, &Base, 1);
return ExprError();
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
<< "->" << Base->getSourceRange();
- PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
return ExprError();
}
@@ -7585,23 +7733,20 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
Best->FoundDecl, Method))
return ExprError();
- // No concerns about early exits now.
- BaseIn.release();
-
// Build the operator call.
Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(),
SourceLocation());
UsualUnaryConversions(FnExpr);
QualType ResultTy = Method->getCallResultType();
- ExprOwningPtr<CXXOperatorCallExpr>
- TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
- &Base, 1, ResultTy, OpLoc));
+ CXXOperatorCallExpr *TheCall =
+ new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
+ &Base, 1, ResultTy, OpLoc);
- if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall.get(),
+ if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,
Method))
return ExprError();
- return move(TheCall);
+ return Owned(TheCall);
}
/// FixOverloadedFunctionReference - E is an expression that refers to
@@ -7626,17 +7771,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
assert(Context.hasSameType(ICE->getSubExpr()->getType(),
SubExpr->getType()) &&
"Implicit cast type cannot be determined from overload");
+ assert(ICE->path_empty() && "fixing up hierarchy conversion?");
if (SubExpr == ICE->getSubExpr())
return ICE->Retain();
- return new (Context) ImplicitCastExpr(ICE->getType(),
- ICE->getCastKind(),
- SubExpr, CXXBaseSpecifierArray(),
- ICE->isLvalueCast());
+ return ImplicitCastExpr::Create(Context, ICE->getType(),
+ ICE->getCastKind(),
+ SubExpr, 0,
+ ICE->getValueKind());
}
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
- assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
+ assert(UnOp->getOpcode() == UO_AddrOf &&
"Can only take the address of an overloaded function");
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
if (Method->isStatic()) {
@@ -7664,7 +7810,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
QualType MemPtrType
= Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
- return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+ return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
MemPtrType, UnOp->getOperatorLoc());
}
}
@@ -7673,7 +7819,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
if (SubExpr == UnOp->getSubExpr())
return UnOp->Retain();
- return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+ return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
Context.getPointerType(SubExpr->getType()),
UnOp->getOperatorLoc());
}
@@ -7732,7 +7878,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
MemExpr->getQualifierRange(),
Fn,
Found,
- MemExpr->getMemberLoc(),
+ MemExpr->getMemberNameInfo(),
TemplateArgs,
Fn->getType());
}
@@ -7741,9 +7887,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
return E->Retain();
}
-Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E,
- DeclAccessPair Found,
- FunctionDecl *Fn) {
+ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
+ DeclAccessPair Found,
+ FunctionDecl *Fn) {
return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
}
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
deleted file mode 100644
index eb4fc6581796..000000000000
--- a/lib/Sema/SemaOverload.h
+++ /dev/null
@@ -1,617 +0,0 @@
-//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the data structures and types used in C++
-// overload resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
-#define LLVM_CLANG_SEMA_OVERLOAD_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
- class ASTContext;
- class CXXConstructorDecl;
- class CXXConversionDecl;
- class FunctionDecl;
-
- /// OverloadingResult - Capture the result of performing overload
- /// resolution.
- enum OverloadingResult {
- OR_Success, ///< Overload resolution succeeded.
- OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous, ///< Ambiguous candidates found.
- OR_Deleted ///< Succeeded, but refers to a deleted function.
- };
-
- /// ImplicitConversionKind - The kind of implicit conversion used to
- /// convert an argument to a parameter's type. The enumerator values
- /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
- /// better conversion kinds have smaller values.
- enum ImplicitConversionKind {
- ICK_Identity = 0, ///< Identity conversion (no conversion)
- ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1)
- ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2)
- ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3)
- ICK_NoReturn_Adjustment, ///< Removal of noreturn from a type (Clang)
- ICK_Qualification, ///< Qualification conversions (C++ 4.4)
- ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
- ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
- ICK_Complex_Promotion, ///< Complex promotions (Clang extension)
- ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7)
- ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8)
- ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6)
- ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9)
- ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10)
- ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11)
- ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12)
- ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
- ICK_Derived_To_Base, ///< Derived-to-base (C++ [over.best.ics])
- ICK_Vector_Conversion, ///< Vector conversions
- ICK_Vector_Splat, ///< A vector splat from an arithmetic type
- ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
- ICK_Num_Conversion_Kinds ///< The number of conversion kinds
- };
-
- /// ImplicitConversionCategory - The category of an implicit
- /// conversion kind. The enumerator values match with Table 9 of
- /// (C++ 13.3.3.1.1) and are listed such that better conversion
- /// categories have smaller values.
- enum ImplicitConversionCategory {
- ICC_Identity = 0, ///< Identity
- ICC_Lvalue_Transformation, ///< Lvalue transformation
- ICC_Qualification_Adjustment, ///< Qualification adjustment
- ICC_Promotion, ///< Promotion
- ICC_Conversion ///< Conversion
- };
-
- ImplicitConversionCategory
- GetConversionCategory(ImplicitConversionKind Kind);
-
- /// ImplicitConversionRank - The rank of an implicit conversion
- /// kind. The enumerator values match with Table 9 of (C++
- /// 13.3.3.1.1) and are listed such that better conversion ranks
- /// have smaller values.
- enum ImplicitConversionRank {
- ICR_Exact_Match = 0, ///< Exact Match
- ICR_Promotion, ///< Promotion
- ICR_Conversion, ///< Conversion
- ICR_Complex_Real_Conversion ///< Complex <-> Real conversion
- };
-
- ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
-
- /// StandardConversionSequence - represents a standard conversion
- /// sequence (C++ 13.3.3.1.1). A standard conversion sequence
- /// contains between zero and three conversions. If a particular
- /// conversion is not needed, it will be set to the identity conversion
- /// (ICK_Identity). Note that the three conversions are
- /// specified as separate members (rather than in an array) so that
- /// we can keep the size of a standard conversion sequence to a
- /// single word.
- struct StandardConversionSequence {
- /// First -- The first conversion can be an lvalue-to-rvalue
- /// conversion, array-to-pointer conversion, or
- /// function-to-pointer conversion.
- ImplicitConversionKind First : 8;
-
- /// Second - The second conversion can be an integral promotion,
- /// floating point promotion, integral conversion, floating point
- /// conversion, floating-integral conversion, pointer conversion,
- /// pointer-to-member conversion, or boolean conversion.
- ImplicitConversionKind Second : 8;
-
- /// Third - The third conversion can be a qualification conversion.
- ImplicitConversionKind Third : 8;
-
- /// Deprecated - Whether this the deprecated conversion of a
- /// string literal to a pointer to non-const character data
- /// (C++ 4.2p2).
- bool DeprecatedStringLiteralToCharPtr : 1;
-
- /// IncompatibleObjC - Whether this is an Objective-C conversion
- /// that we should warn about (if we actually use it).
- bool IncompatibleObjC : 1;
-
- /// ReferenceBinding - True when this is a reference binding
- /// (C++ [over.ics.ref]).
- bool ReferenceBinding : 1;
-
- /// DirectBinding - True when this is a reference binding that is a
- /// direct binding (C++ [dcl.init.ref]).
- bool DirectBinding : 1;
-
- /// RRefBinding - True when this is a reference binding of an rvalue
- /// reference to an rvalue (C++0x [over.ics.rank]p3b4).
- bool RRefBinding : 1;
-
- /// FromType - The type that this conversion is converting
- /// from. This is an opaque pointer that can be translated into a
- /// QualType.
- void *FromTypePtr;
-
- /// ToType - The types that this conversion is converting to in
- /// each step. This is an opaque pointer that can be translated
- /// into a QualType.
- void *ToTypePtrs[3];
-
- /// CopyConstructor - The copy constructor that is used to perform
- /// this conversion, when the conversion is actually just the
- /// initialization of an object via copy constructor. Such
- /// conversions are either identity conversions or derived-to-base
- /// conversions.
- CXXConstructorDecl *CopyConstructor;
-
- void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
- void setToType(unsigned Idx, QualType T) {
- assert(Idx < 3 && "To type index is out of range");
- ToTypePtrs[Idx] = T.getAsOpaquePtr();
- }
- void setAllToTypes(QualType T) {
- ToTypePtrs[0] = T.getAsOpaquePtr();
- ToTypePtrs[1] = ToTypePtrs[0];
- ToTypePtrs[2] = ToTypePtrs[0];
- }
-
- QualType getFromType() const {
- return QualType::getFromOpaquePtr(FromTypePtr);
- }
- QualType getToType(unsigned Idx) const {
- assert(Idx < 3 && "To type index is out of range");
- return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
- }
-
- void setAsIdentityConversion();
-
- bool isIdentityConversion() const {
- return First == ICK_Identity && Second == ICK_Identity &&
- Third == ICK_Identity;
- }
-
- ImplicitConversionRank getRank() const;
- bool isPointerConversionToBool() const;
- bool isPointerConversionToVoidPointer(ASTContext& Context) const;
- void DebugPrint() const;
- };
-
- /// UserDefinedConversionSequence - Represents a user-defined
- /// conversion sequence (C++ 13.3.3.1.2).
- struct UserDefinedConversionSequence {
- /// Before - Represents the standard conversion that occurs before
- /// the actual user-defined conversion. (C++ 13.3.3.1.2p1):
- ///
- /// If the user-defined conversion is specified by a constructor
- /// (12.3.1), the initial standard conversion sequence converts
- /// the source type to the type required by the argument of the
- /// constructor. If the user-defined conversion is specified by
- /// a conversion function (12.3.2), the initial standard
- /// conversion sequence converts the source type to the implicit
- /// object parameter of the conversion function.
- StandardConversionSequence Before;
-
- /// EllipsisConversion - When this is true, it means user-defined
- /// conversion sequence starts with a ... (elipsis) conversion, instead of
- /// a standard conversion. In this case, 'Before' field must be ignored.
- // FIXME. I much rather put this as the first field. But there seems to be
- // a gcc code gen. bug which causes a crash in a test. Putting it here seems
- // to work around the crash.
- bool EllipsisConversion : 1;
-
- /// After - Represents the standard conversion that occurs after
- /// the actual user-defined conversion.
- StandardConversionSequence After;
-
- /// ConversionFunction - The function that will perform the
- /// user-defined conversion.
- FunctionDecl* ConversionFunction;
-
- void DebugPrint() const;
- };
-
- /// Represents an ambiguous user-defined conversion sequence.
- struct AmbiguousConversionSequence {
- typedef llvm::SmallVector<FunctionDecl*, 4> ConversionSet;
-
- void *FromTypePtr;
- void *ToTypePtr;
- char Buffer[sizeof(ConversionSet)];
-
- QualType getFromType() const {
- return QualType::getFromOpaquePtr(FromTypePtr);
- }
- QualType getToType() const {
- return QualType::getFromOpaquePtr(ToTypePtr);
- }
- void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
- void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
-
- ConversionSet &conversions() {
- return *reinterpret_cast<ConversionSet*>(Buffer);
- }
-
- const ConversionSet &conversions() const {
- return *reinterpret_cast<const ConversionSet*>(Buffer);
- }
-
- void addConversion(FunctionDecl *D) {
- conversions().push_back(D);
- }
-
- typedef ConversionSet::iterator iterator;
- iterator begin() { return conversions().begin(); }
- iterator end() { return conversions().end(); }
-
- typedef ConversionSet::const_iterator const_iterator;
- const_iterator begin() const { return conversions().begin(); }
- const_iterator end() const { return conversions().end(); }
-
- void construct();
- void destruct();
- void copyFrom(const AmbiguousConversionSequence &);
- };
-
- /// BadConversionSequence - Records information about an invalid
- /// conversion sequence.
- struct BadConversionSequence {
- enum FailureKind {
- no_conversion,
- unrelated_class,
- suppressed_user,
- bad_qualifiers
- };
-
- // This can be null, e.g. for implicit object arguments.
- Expr *FromExpr;
-
- FailureKind Kind;
-
- private:
- // The type we're converting from (an opaque QualType).
- void *FromTy;
-
- // The type we're converting to (an opaque QualType).
- void *ToTy;
-
- public:
- void init(FailureKind K, Expr *From, QualType To) {
- init(K, From->getType(), To);
- FromExpr = From;
- }
- void init(FailureKind K, QualType From, QualType To) {
- Kind = K;
- FromExpr = 0;
- setFromType(From);
- setToType(To);
- }
-
- QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); }
- QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); }
-
- void setFromExpr(Expr *E) {
- FromExpr = E;
- setFromType(E->getType());
- }
- void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
- void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
- };
-
- /// ImplicitConversionSequence - Represents an implicit conversion
- /// sequence, which may be a standard conversion sequence
- /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
- /// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
- struct ImplicitConversionSequence {
- /// Kind - The kind of implicit conversion sequence. BadConversion
- /// specifies that there is no conversion from the source type to
- /// the target type. AmbiguousConversion represents the unique
- /// ambiguous conversion (C++0x [over.best.ics]p10).
- enum Kind {
- StandardConversion = 0,
- UserDefinedConversion,
- AmbiguousConversion,
- EllipsisConversion,
- BadConversion
- };
-
- private:
- enum {
- Uninitialized = BadConversion + 1
- };
-
- /// ConversionKind - The kind of implicit conversion sequence.
- unsigned ConversionKind;
-
- void setKind(Kind K) {
- destruct();
- ConversionKind = K;
- }
-
- void destruct() {
- if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
- }
-
- public:
- union {
- /// When ConversionKind == StandardConversion, provides the
- /// details of the standard conversion sequence.
- StandardConversionSequence Standard;
-
- /// When ConversionKind == UserDefinedConversion, provides the
- /// details of the user-defined conversion sequence.
- UserDefinedConversionSequence UserDefined;
-
- /// When ConversionKind == AmbiguousConversion, provides the
- /// details of the ambiguous conversion.
- AmbiguousConversionSequence Ambiguous;
-
- /// When ConversionKind == BadConversion, provides the details
- /// of the bad conversion.
- BadConversionSequence Bad;
- };
-
- ImplicitConversionSequence() : ConversionKind(Uninitialized) {}
- ~ImplicitConversionSequence() {
- destruct();
- }
- ImplicitConversionSequence(const ImplicitConversionSequence &Other)
- : ConversionKind(Other.ConversionKind)
- {
- switch (ConversionKind) {
- case Uninitialized: break;
- case StandardConversion: Standard = Other.Standard; break;
- case UserDefinedConversion: UserDefined = Other.UserDefined; break;
- case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
- case EllipsisConversion: break;
- case BadConversion: Bad = Other.Bad; break;
- }
- }
-
- ImplicitConversionSequence &
- operator=(const ImplicitConversionSequence &Other) {
- destruct();
- new (this) ImplicitConversionSequence(Other);
- return *this;
- }
-
- Kind getKind() const {
- assert(isInitialized() && "querying uninitialized conversion");
- return Kind(ConversionKind);
- }
-
- /// \brief Return a ranking of the implicit conversion sequence
- /// kind, where smaller ranks represent better conversion
- /// sequences.
- ///
- /// In particular, this routine gives user-defined conversion
- /// sequences and ambiguous conversion sequences the same rank,
- /// per C++ [over.best.ics]p10.
- unsigned getKindRank() const {
- switch (getKind()) {
- case StandardConversion:
- return 0;
-
- case UserDefinedConversion:
- case AmbiguousConversion:
- return 1;
-
- case EllipsisConversion:
- return 2;
-
- case BadConversion:
- return 3;
- }
-
- return 3;
- }
-
- bool isBad() const { return getKind() == BadConversion; }
- bool isStandard() const { return getKind() == StandardConversion; }
- bool isEllipsis() const { return getKind() == EllipsisConversion; }
- bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
- bool isUserDefined() const { return getKind() == UserDefinedConversion; }
-
- /// Determines whether this conversion sequence has been
- /// initialized. Most operations should never need to query
- /// uninitialized conversions and should assert as above.
- bool isInitialized() const { return ConversionKind != Uninitialized; }
-
- /// Sets this sequence as a bad conversion for an explicit argument.
- void setBad(BadConversionSequence::FailureKind Failure,
- Expr *FromExpr, QualType ToType) {
- setKind(BadConversion);
- Bad.init(Failure, FromExpr, ToType);
- }
-
- /// Sets this sequence as a bad conversion for an implicit argument.
- void setBad(BadConversionSequence::FailureKind Failure,
- QualType FromType, QualType ToType) {
- setKind(BadConversion);
- Bad.init(Failure, FromType, ToType);
- }
-
- void setStandard() { setKind(StandardConversion); }
- void setEllipsis() { setKind(EllipsisConversion); }
- void setUserDefined() { setKind(UserDefinedConversion); }
- void setAmbiguous() {
- if (ConversionKind == AmbiguousConversion) return;
- ConversionKind = AmbiguousConversion;
- Ambiguous.construct();
- }
-
- // The result of a comparison between implicit conversion
- // sequences. Use Sema::CompareImplicitConversionSequences to
- // actually perform the comparison.
- enum CompareKind {
- Better = -1,
- Indistinguishable = 0,
- Worse = 1
- };
-
- void DebugPrint() const;
- };
-
- enum OverloadFailureKind {
- ovl_fail_too_many_arguments,
- ovl_fail_too_few_arguments,
- ovl_fail_bad_conversion,
- ovl_fail_bad_deduction,
-
- /// This conversion candidate was not considered because it
- /// duplicates the work of a trivial or derived-to-base
- /// conversion.
- ovl_fail_trivial_conversion,
-
- /// This conversion candidate is not viable because its result
- /// type is not implicitly convertible to the desired type.
- ovl_fail_bad_final_conversion,
-
- /// This conversion function template specialization candidate is not
- /// viable because the final conversion was not an exact match.
- ovl_fail_final_conversion_not_exact
- };
-
- /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
- struct OverloadCandidate {
- /// Function - The actual function that this candidate
- /// represents. When NULL, this is a built-in candidate
- /// (C++ [over.oper]) or a surrogate for a conversion to a
- /// function pointer or reference (C++ [over.call.object]).
- FunctionDecl *Function;
-
- /// FoundDecl - The original declaration that was looked up /
- /// invented / otherwise found, together with its access.
- /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
- DeclAccessPair FoundDecl;
-
- // BuiltinTypes - Provides the return and parameter types of a
- // built-in overload candidate. Only valid when Function is NULL.
- struct {
- QualType ResultTy;
- QualType ParamTypes[3];
- } BuiltinTypes;
-
- /// Surrogate - The conversion function for which this candidate
- /// is a surrogate, but only if IsSurrogate is true.
- CXXConversionDecl *Surrogate;
-
- /// Conversions - The conversion sequences used to convert the
- /// function arguments to the function parameters.
- llvm::SmallVector<ImplicitConversionSequence, 4> Conversions;
-
- /// Viable - True to indicate that this overload candidate is viable.
- bool Viable;
-
- /// IsSurrogate - True to indicate that this candidate is a
- /// surrogate for a conversion to a function pointer or reference
- /// (C++ [over.call.object]).
- bool IsSurrogate;
-
- /// IgnoreObjectArgument - True to indicate that the first
- /// argument's conversion, which for this function represents the
- /// implicit object argument, should be ignored. This will be true
- /// when the candidate is a static member function (where the
- /// implicit object argument is just a placeholder) or a
- /// non-static member function when the call doesn't have an
- /// object argument.
- bool IgnoreObjectArgument;
-
- /// FailureKind - The reason why this candidate is not viable.
- /// Actually an OverloadFailureKind.
- unsigned char FailureKind;
-
- /// A structure used to record information about a failed
- /// template argument deduction.
- struct DeductionFailureInfo {
- // A Sema::TemplateDeductionResult.
- unsigned Result;
-
- /// \brief Opaque pointer containing additional data about
- /// this deduction failure.
- void *Data;
-
- /// \brief Retrieve the template parameter this deduction failure
- /// refers to, if any.
- TemplateParameter getTemplateParameter();
-
- /// \brief Retrieve the template argument list associated with this
- /// deduction failure, if any.
- TemplateArgumentList *getTemplateArgumentList();
-
- /// \brief Return the first template argument this deduction failure
- /// refers to, if any.
- const TemplateArgument *getFirstArg();
-
- /// \brief Return the second template argument this deduction failure
- /// refers to, if any.
- const TemplateArgument *getSecondArg();
-
- /// \brief Free any memory associated with this deduction failure.
- void Destroy();
- };
-
- union {
- DeductionFailureInfo DeductionFailure;
-
- /// FinalConversion - For a conversion function (where Function is
- /// a CXXConversionDecl), the standard conversion that occurs
- /// after the call to the overload candidate to convert the result
- /// of calling the conversion function to the required type.
- StandardConversionSequence FinalConversion;
- };
-
- /// hasAmbiguousConversion - Returns whether this overload
- /// candidate requires an ambiguous conversion or not.
- bool hasAmbiguousConversion() const {
- for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator
- I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
- if (!I->isInitialized()) return false;
- if (I->isAmbiguous()) return true;
- }
- return false;
- }
- };
-
- /// OverloadCandidateSet - A set of overload candidates, used in C++
- /// overload resolution (C++ 13.3).
- class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> {
- typedef llvm::SmallVector<OverloadCandidate, 16> inherited;
- llvm::SmallPtrSet<Decl *, 16> Functions;
-
- SourceLocation Loc;
-
- OverloadCandidateSet(const OverloadCandidateSet &);
- OverloadCandidateSet &operator=(const OverloadCandidateSet &);
-
- public:
- OverloadCandidateSet(SourceLocation Loc) : Loc(Loc) {}
-
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine when this overload candidate will be new to the
- /// overload set.
- bool isNewCandidate(Decl *F) {
- return Functions.insert(F->getCanonicalDecl());
- }
-
- /// \brief Clear out all of the candidates.
- void clear();
-
- ~OverloadCandidateSet() { clear(); }
- };
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9c8f48bfea17..083e4dba85e3 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -11,8 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Initialization.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
@@ -26,19 +28,11 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
using namespace clang;
+using namespace sema;
-Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
- Expr *E = expr->takeAs<Expr>();
+StmtResult Sema::ActOnExprStmt(FullExprArg expr) {
+ Expr *E = expr.get();
assert(E && "ActOnExprStmt(): missing expression");
- if (E->getType()->isObjCObjectType()) {
- if (LangOpts.ObjCNonFragileABI)
- Diag(E->getLocEnd(), diag::err_indirection_requires_nonfragile_object)
- << E->getType();
- else
- Diag(E->getLocEnd(), diag::err_direct_interface_unsupported)
- << E->getType();
- return StmtError();
- }
// C99 6.8.3p2: The expression in an expression statement is evaluated as a
// void expression for its side effects. Conversion to void allows any
// operand, even incomplete types.
@@ -48,11 +42,11 @@ Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
}
-Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
+StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
return Owned(new (Context) NullStmt(SemiLoc));
}
-Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
+StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
SourceLocation StartLoc,
SourceLocation EndLoc) {
DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
@@ -141,10 +135,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
}
}
- Diag(Loc, DiagID) << R1 << R2;
+ DiagRuntimeBehavior(Loc, PDiag(DiagID) << R1 << R2);
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
MultiStmtArg elts, bool isStmtExpr) {
unsigned NumElts = elts.size();
@@ -179,70 +173,60 @@ Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
}
-Action::OwningStmtResult
-Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprArg lhsval,
- SourceLocation DotDotDotLoc, ExprArg rhsval,
+StmtResult
+Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
+ SourceLocation DotDotDotLoc, Expr *RHSVal,
SourceLocation ColonLoc) {
- assert((lhsval.get() != 0) && "missing expression in case statement");
+ assert((LHSVal != 0) && "missing expression in case statement");
// C99 6.8.4.2p3: The expression shall be an integer constant.
// However, GCC allows any evaluatable integer expression.
- Expr *LHSVal = static_cast<Expr*>(lhsval.get());
if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent() &&
VerifyIntegerConstantExpression(LHSVal))
return StmtError();
// GCC extension: The expression shall be an integer constant.
- Expr *RHSVal = static_cast<Expr*>(rhsval.get());
if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent() &&
VerifyIntegerConstantExpression(RHSVal)) {
RHSVal = 0; // Recover by just forgetting about it.
- rhsval = 0;
}
- if (getSwitchStack().empty()) {
+ if (getCurFunction()->SwitchStack.empty()) {
Diag(CaseLoc, diag::err_case_not_in_switch);
return StmtError();
}
- // Only now release the smart pointers.
- lhsval.release();
- rhsval.release();
CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
ColonLoc);
- getSwitchStack().back()->addSwitchCase(CS);
+ getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
return Owned(CS);
}
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
-void Sema::ActOnCaseStmtBody(StmtTy *caseStmt, StmtArg subStmt) {
+void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
- Stmt *SubStmt = subStmt.takeAs<Stmt>();
CS->setSubStmt(SubStmt);
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
- StmtArg subStmt, Scope *CurScope) {
- Stmt *SubStmt = subStmt.takeAs<Stmt>();
-
- if (getSwitchStack().empty()) {
+ Stmt *SubStmt, Scope *CurScope) {
+ if (getCurFunction()->SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
return Owned(SubStmt);
}
DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
- getSwitchStack().back()->addSwitchCase(DS);
+ getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
return Owned(DS);
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, StmtArg subStmt) {
- Stmt *SubStmt = subStmt.takeAs<Stmt>();
+ SourceLocation ColonLoc, Stmt *SubStmt) {
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = getLabelMap()[II];
+ LabelStmt *&LabelDecl = getCurFunction()->LabelMap[II];
// If not forward referenced or defined already, just create a new LabelStmt.
if (LabelDecl == 0)
@@ -265,15 +249,15 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
return Owned(LabelDecl);
}
-Action::OwningStmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
- StmtArg ThenVal, SourceLocation ElseLoc,
- StmtArg ElseVal) {
- OwningExprResult CondResult(CondVal.release());
+StmtResult
+Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
+ Stmt *thenStmt, SourceLocation ElseLoc,
+ Stmt *elseStmt) {
+ ExprResult CondResult(CondVal.release());
VarDecl *ConditionVar = 0;
- if (CondVar.get()) {
- ConditionVar = CondVar.getAs<VarDecl>();
+ if (CondVar) {
+ ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
if (CondResult.isInvalid())
return StmtError();
@@ -282,22 +266,19 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
if (!ConditionExpr)
return StmtError();
- Stmt *thenStmt = ThenVal.takeAs<Stmt>();
DiagnoseUnusedExprResult(thenStmt);
// Warn if the if block has a null body without an else value.
// this helps prevent bugs due to typos, such as
// if (condition);
// do_stuff();
- if (!ElseVal.get()) {
+ if (!elseStmt) {
if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
}
- Stmt *elseStmt = ElseVal.takeAs<Stmt>();
DiagnoseUnusedExprResult(elseStmt);
- CondResult.release();
return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
thenStmt, ElseLoc, elseStmt));
}
@@ -404,64 +385,63 @@ static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) {
return expr->getType();
}
-Action::OwningStmtResult
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ExprArg Cond,
- DeclPtrTy CondVar) {
+StmtResult
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
+ Decl *CondVar) {
+ ExprResult CondResult;
+
VarDecl *ConditionVar = 0;
- if (CondVar.get()) {
- ConditionVar = CondVar.getAs<VarDecl>();
- OwningExprResult CondE = CheckConditionVariable(ConditionVar, SourceLocation(), false);
- if (CondE.isInvalid())
+ if (CondVar) {
+ ConditionVar = cast<VarDecl>(CondVar);
+ CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
+ if (CondResult.isInvalid())
return StmtError();
- Cond = move(CondE);
+ Cond = CondResult.release();
}
- if (!Cond.get())
+ if (!Cond)
return StmtError();
- Expr *CondExpr = static_cast<Expr *>(Cond.get());
- OwningExprResult ConvertedCond
- = ConvertToIntegralOrEnumerationType(SwitchLoc, move(Cond),
+ CondResult
+ = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond,
PDiag(diag::err_typecheck_statement_requires_integer),
PDiag(diag::err_switch_incomplete_class_type)
- << CondExpr->getSourceRange(),
+ << Cond->getSourceRange(),
PDiag(diag::err_switch_explicit_conversion),
PDiag(diag::note_switch_conversion),
PDiag(diag::err_switch_multiple_conversions),
PDiag(diag::note_switch_conversion),
PDiag(0));
- if (ConvertedCond.isInvalid())
- return StmtError();
+ if (CondResult.isInvalid()) return StmtError();
+ Cond = CondResult.take();
- CondExpr = ConvertedCond.takeAs<Expr>();
-
- if (!CondVar.get()) {
- CondExpr = MaybeCreateCXXExprWithTemporaries(CondExpr);
- if (!CondExpr)
+ if (!CondVar) {
+ CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+ if (CondResult.isInvalid())
return StmtError();
+ Cond = CondResult.take();
}
+
+ getCurFunction()->setHasBranchIntoScope();
- SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, CondExpr);
- getSwitchStack().push_back(SS);
+ SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
+ getCurFunction()->SwitchStack.push_back(SS);
return Owned(SS);
}
-Action::OwningStmtResult
-Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
- StmtArg Body) {
- Stmt *BodyStmt = Body.takeAs<Stmt>();
-
- SwitchStmt *SS = getSwitchStack().back();
- assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!");
+StmtResult
+Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
+ Stmt *BodyStmt) {
+ SwitchStmt *SS = cast<SwitchStmt>(Switch);
+ assert(SS == getCurFunction()->SwitchStack.back() &&
+ "switch stack missing push/pop!");
SS->setBody(BodyStmt, SwitchLoc);
- getSwitchStack().pop_back();
+ getCurFunction()->SwitchStack.pop_back();
- if (SS->getCond() == 0) {
- SS->Destroy(Context);
+ if (SS->getCond() == 0)
return StmtError();
- }
Expr *CondExpr = SS->getCond();
Expr *CondExprBeforePromotion = CondExpr;
@@ -556,7 +536,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
// If the LHS is not the same type as the condition, insert an implicit
// cast.
- ImpCastExprToType(Lo, CondType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Lo, CondType, CK_IntegralCast);
CS->setLHS(Lo);
// If this is a case range, remember it in CaseRanges, otherwise CaseVals.
@@ -635,7 +615,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
// If the LHS is not the same type as the condition, insert an implicit
// cast.
- ImpCastExprToType(Hi, CondType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Hi, CondType, CK_IntegralCast);
CR->setRHS(Hi);
// If the low value is bigger than the high value, the case is empty.
@@ -804,65 +784,55 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
if (CaseListIsErroneous)
return StmtError();
- Switch.release();
return Owned(SS);
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
- DeclPtrTy CondVar, StmtArg Body) {
- OwningExprResult CondResult(Cond.release());
+ Decl *CondVar, Stmt *Body) {
+ ExprResult CondResult(Cond.release());
VarDecl *ConditionVar = 0;
- if (CondVar.get()) {
- ConditionVar = CondVar.getAs<VarDecl>();
+ if (CondVar) {
+ ConditionVar = cast<VarDecl>(CondVar);
CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
if (CondResult.isInvalid())
return StmtError();
}
- Expr *ConditionExpr = CondResult.takeAs<Expr>();
+ Expr *ConditionExpr = CondResult.take();
if (!ConditionExpr)
return StmtError();
- Stmt *bodyStmt = Body.takeAs<Stmt>();
- DiagnoseUnusedExprResult(bodyStmt);
+ DiagnoseUnusedExprResult(Body);
- CondResult.release();
return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
- bodyStmt, WhileLoc));
+ Body, WhileLoc));
}
-Action::OwningStmtResult
-Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+StmtResult
+Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
SourceLocation WhileLoc, SourceLocation CondLParen,
- ExprArg Cond, SourceLocation CondRParen) {
- Expr *condExpr = Cond.takeAs<Expr>();
- assert(condExpr && "ActOnDoStmt(): missing expression");
+ Expr *Cond, SourceLocation CondRParen) {
+ assert(Cond && "ActOnDoStmt(): missing expression");
- if (CheckBooleanCondition(condExpr, DoLoc)) {
- Cond = condExpr;
+ if (CheckBooleanCondition(Cond, DoLoc))
return StmtError();
- }
- condExpr = MaybeCreateCXXExprWithTemporaries(condExpr);
- if (!condExpr)
+ ExprResult CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+ if (CondResult.isInvalid())
return StmtError();
+ Cond = CondResult.take();
- Stmt *bodyStmt = Body.takeAs<Stmt>();
- DiagnoseUnusedExprResult(bodyStmt);
+ DiagnoseUnusedExprResult(Body);
- Cond.release();
- return Owned(new (Context) DoStmt(bodyStmt, condExpr, DoLoc,
- WhileLoc, CondRParen));
+ return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
- StmtArg first, FullExprArg second, DeclPtrTy secondVar,
+ Stmt *First, FullExprArg second, Decl *secondVar,
FullExprArg third,
- SourceLocation RParenLoc, StmtArg body) {
- Stmt *First = static_cast<Stmt*>(first.get());
-
+ SourceLocation RParenLoc, Stmt *Body) {
if (!getLangOptions().CPlusPlus) {
if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
// C99 6.8.5p3: The declaration part of a 'for' statement shall only
@@ -880,38 +850,32 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
}
}
- OwningExprResult SecondResult(second.release());
+ ExprResult SecondResult(second.release());
VarDecl *ConditionVar = 0;
- if (secondVar.get()) {
- ConditionVar = secondVar.getAs<VarDecl>();
+ if (secondVar) {
+ ConditionVar = cast<VarDecl>(secondVar);
SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
if (SecondResult.isInvalid())
return StmtError();
}
Expr *Third = third.release().takeAs<Expr>();
- Stmt *Body = static_cast<Stmt*>(body.get());
DiagnoseUnusedExprResult(First);
DiagnoseUnusedExprResult(Third);
DiagnoseUnusedExprResult(Body);
- first.release();
- body.release();
return Owned(new (Context) ForStmt(Context, First,
- SecondResult.takeAs<Expr>(), ConditionVar,
+ SecondResult.take(), ConditionVar,
Third, Body, ForLoc, LParenLoc,
RParenLoc));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
- StmtArg first, ExprArg second,
- SourceLocation RParenLoc, StmtArg body) {
- Stmt *First = static_cast<Stmt*>(first.get());
- Expr *Second = static_cast<Expr*>(second.get());
- Stmt *Body = static_cast<Stmt*>(body.get());
+ Stmt *First, Expr *Second,
+ SourceLocation RParenLoc, Stmt *Body) {
if (First) {
QualType FirstType;
if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
@@ -950,19 +914,39 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
if (!SecondType->isObjCObjectPointerType())
Diag(ForLoc, diag::err_collection_expr_type)
<< SecondType << Second->getSourceRange();
+ else if (const ObjCObjectPointerType *OPT =
+ SecondType->getAsObjCInterfacePointerType()) {
+ llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
+ IdentifierInfo* selIdent =
+ &Context.Idents.get("countByEnumeratingWithState");
+ KeyIdents.push_back(selIdent);
+ selIdent = &Context.Idents.get("objects");
+ KeyIdents.push_back(selIdent);
+ selIdent = &Context.Idents.get("count");
+ KeyIdents.push_back(selIdent);
+ Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
+ if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
+ if (!IDecl->isForwardDecl() &&
+ !IDecl->lookupInstanceMethod(CSelector)) {
+ // Must further look into private implementation methods.
+ if (!LookupPrivateInstanceMethod(CSelector, IDecl))
+ Diag(ForLoc, diag::warn_collection_expr_type)
+ << SecondType << CSelector << Second->getSourceRange();
+ }
+ }
+ }
}
- first.release();
- second.release();
- body.release();
return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body,
ForLoc, RParenLoc));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
IdentifierInfo *LabelII) {
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+ LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
+
+ getCurFunction()->setHasBranchIntoScope();
// If we haven't seen this label yet, create a forward reference.
if (LabelDecl == 0)
@@ -971,11 +955,10 @@ Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
- ExprArg DestExp) {
+ Expr *E) {
// Convert operand to void*
- Expr* E = DestExp.takeAs<Expr>();
if (!E->isTypeDependent()) {
QualType ETy = E->getType();
QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
@@ -984,10 +967,13 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
return StmtError();
}
+
+ getCurFunction()->setHasIndirectGoto();
+
return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
Scope *S = CurScope->getContinueParent();
if (!S) {
@@ -998,7 +984,7 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
return Owned(new (Context) ContinueStmt(ContinueLoc));
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
Scope *S = CurScope->getBreakParent();
if (!S) {
@@ -1050,7 +1036,7 @@ static const VarDecl *getNRVOCandidate(ASTContext &Ctx, QualType RetType,
/// ActOnBlockReturnStmt - Utility routine to figure out block's return type.
///
-Action::OwningStmtResult
+StmtResult
Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// If this is the first return we've seen in the block, infer the type of
// the block from it.
@@ -1086,7 +1072,6 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (CurBlock->ReturnType->isVoidType()) {
if (RetValExp) {
Diag(ReturnLoc, diag::err_return_block_has_expr);
- RetValExp->Destroy(Context);
RetValExp = 0;
}
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
@@ -1105,7 +1090,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// In C++ the return statement is handled via a copy initialization.
// the C version of which boils down to CheckSingleAssignmentConstraints.
NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
- OwningExprResult Res = PerformCopyInitialization(
+ ExprResult Res = PerformCopyInitialization(
InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
NRVOCandidate != 0),
@@ -1136,9 +1121,8 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
return Owned(Result);
}
-Action::OwningStmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
- Expr *RetValExp = rex.takeAs<Expr>();
+StmtResult
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (getCurBlock())
return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
@@ -1197,7 +1181,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
// In C++ the return statement is handled via a copy initialization.
// the C version of which boils down to CheckSingleAssignmentConstraints.
NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
- OwningExprResult Res = PerformCopyInitialization(
+ ExprResult Res = PerformCopyInitialization(
InitializedEntity::InitializeResult(ReturnLoc,
FnRetType,
NRVOCandidate != 0),
@@ -1261,7 +1245,7 @@ static bool CheckAsmLValue(const Expr *E, Sema &S) {
}
-Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
bool IsVolatile,
unsigned NumOutputs,
@@ -1269,15 +1253,15 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
IdentifierInfo **Names,
MultiExprArg constraints,
MultiExprArg exprs,
- ExprArg asmString,
+ Expr *asmString,
MultiExprArg clobbers,
SourceLocation RParenLoc,
bool MSAsm) {
unsigned NumClobbers = clobbers.size();
StringLiteral **Constraints =
reinterpret_cast<StringLiteral**>(constraints.get());
- Expr **Exprs = reinterpret_cast<Expr **>(exprs.get());
- StringLiteral *AsmString = cast<StringLiteral>((Expr *)asmString.get());
+ Expr **Exprs = exprs.get();
+ StringLiteral *AsmString = cast<StringLiteral>(asmString);
StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
@@ -1373,10 +1357,6 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
diag::err_asm_unknown_register_name) << Clobber);
}
- constraints.release();
- exprs.release();
- asmString.release();
- clobbers.release();
AsmStmt *NS =
new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm,
NumOutputs, NumInputs, Names, Constraints, Exprs,
@@ -1388,7 +1368,6 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
<< AsmString->getSourceRange();
- DeleteStmt(NS);
return StmtError();
}
@@ -1479,45 +1458,41 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
diag::err_asm_tying_incompatible_types)
<< InTy << OutTy << OutputExpr->getSourceRange()
<< InputExpr->getSourceRange();
- DeleteStmt(NS);
return StmtError();
}
return Owned(NS);
}
-Action::OwningStmtResult
+StmtResult
Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
- SourceLocation RParen, DeclPtrTy Parm,
- StmtArg Body) {
- VarDecl *Var = cast_or_null<VarDecl>(Parm.getAs<Decl>());
+ SourceLocation RParen, Decl *Parm,
+ Stmt *Body) {
+ VarDecl *Var = cast_or_null<VarDecl>(Parm);
if (Var && Var->isInvalidDecl())
return StmtError();
- return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var,
- Body.takeAs<Stmt>()));
+ return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
}
-Action::OwningStmtResult
-Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
- return Owned(new (Context) ObjCAtFinallyStmt(AtLoc,
- static_cast<Stmt*>(Body.release())));
+StmtResult
+Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
+ return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
}
-Action::OwningStmtResult
-Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, StmtArg Try,
- MultiStmtArg CatchStmts, StmtArg Finally) {
- FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
+ MultiStmtArg CatchStmts, Stmt *Finally) {
+ getCurFunction()->setHasBranchProtectedScope();
unsigned NumCatchStmts = CatchStmts.size();
- return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try.takeAs<Stmt>(),
- (Stmt **)CatchStmts.release(),
+ return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
+ CatchStmts.release(),
NumCatchStmts,
- Finally.takeAs<Stmt>()));
+ Finally));
}
-Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
- ExprArg ThrowE) {
- Expr *Throw = static_cast<Expr *>(ThrowE.get());
+StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
+ Expr *Throw) {
if (Throw) {
QualType ThrowType = Throw->getType();
// Make sure the expression type is an ObjC pointer or "void *".
@@ -1530,13 +1505,13 @@ Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
}
}
- return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowE.takeAs<Expr>()));
+ return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
}
-Action::OwningStmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw,
+StmtResult
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
Scope *CurScope) {
- if (!Throw.get()) {
+ if (!Throw) {
// @throw without an expression designates a rethrow (which much occur
// in the context of an @catch clause).
Scope *AtCatchParent = CurScope;
@@ -1546,16 +1521,15 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw,
return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
}
- return BuildObjCAtThrowStmt(AtLoc, move(Throw));
+ return BuildObjCAtThrowStmt(AtLoc, Throw);
}
-Action::OwningStmtResult
-Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
- StmtArg SynchBody) {
- FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
+ Stmt *SyncBody) {
+ getCurFunction()->setHasBranchProtectedScope();
// Make sure the expression type is an ObjC pointer or "void *".
- Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get());
if (!SyncExpr->getType()->isDependentType() &&
!SyncExpr->getType()->isObjCObjectPointerType()) {
const PointerType *PT = SyncExpr->getType()->getAs<PointerType>();
@@ -1564,22 +1538,22 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
<< SyncExpr->getType() << SyncExpr->getSourceRange());
}
- return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
- SynchExpr.takeAs<Stmt>(),
- SynchBody.takeAs<Stmt>()));
+ return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
}
/// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
/// and creates a proper catch handler from them.
-Action::OwningStmtResult
-Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclPtrTy ExDecl,
- StmtArg HandlerBlock) {
+StmtResult
+Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
+ Stmt *HandlerBlock) {
// There's nothing to test that ActOnExceptionDecl didn't already test.
return Owned(new (Context) CXXCatchStmt(CatchLoc,
- cast_or_null<VarDecl>(ExDecl.getAs<Decl>()),
- HandlerBlock.takeAs<Stmt>()));
+ cast_or_null<VarDecl>(ExDecl),
+ HandlerBlock));
}
+namespace {
+
class TypeWithHandler {
QualType t;
CXXCatchStmt *stmt;
@@ -1602,22 +1576,23 @@ public:
return t == other.t;
}
- QualType getQualType() const { return t; }
CXXCatchStmt *getCatchStmt() const { return stmt; }
SourceLocation getTypeSpecStartLoc() const {
return stmt->getExceptionDecl()->getTypeSpecStartLoc();
}
};
+}
+
/// ActOnCXXTryBlock - Takes a try compound-statement and a number of
/// handlers and creates a try statement from them.
-Action::OwningStmtResult
-Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
+StmtResult
+Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
MultiStmtArg RawHandlers) {
unsigned NumHandlers = RawHandlers.size();
assert(NumHandlers > 0 &&
"The parser shouldn't call this if there are no handlers.");
- Stmt **Handlers = reinterpret_cast<Stmt**>(RawHandlers.get());
+ Stmt **Handlers = RawHandlers.get();
llvm::SmallVector<TypeWithHandler, 8> TypesWithHandlers;
@@ -1657,15 +1632,14 @@ Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
}
}
+ getCurFunction()->setHasBranchProtectedScope();
+
// FIXME: We should detect handlers that cannot catch anything because an
// earlier handler catches a superclass. Need to find a method that is not
// quadratic for this.
// Neither of these are explicitly forbidden, but every compiler detects them
// and warns.
- FunctionNeedsScopeChecking() = true;
- RawHandlers.release();
- return Owned(CXXTryStmt::Create(Context, TryLoc,
- static_cast<Stmt*>(TryBlock.release()),
+ return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock,
Handlers, NumHandlers));
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f121954eed6e..0fc83927b79c 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -9,20 +9,24 @@
// This file implements semantic analysis for C++ templates.
//===----------------------------------------------------------------------===/
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "TreeTransform.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/StringExtras.h"
using namespace clang;
+using namespace sema;
/// \brief Determine whether the declaration found is acceptable as the name
/// of a template and, if so, return that template declaration. Otherwise,
@@ -88,8 +92,13 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
filter.erase();
continue;
}
-
- filter.replace(Repl);
+
+ // FIXME: we promote access to public here as a workaround to
+ // the fact that LookupResult doesn't let us remember that we
+ // found this template through a particular injected class name,
+ // which means we end up doing nasty things to the invariants.
+ // Pretending that access is public is *much* safer.
+ filter.replace(Repl, AS_public);
}
}
filter.done();
@@ -97,8 +106,9 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
TemplateNameKind Sema::isTemplateName(Scope *S,
CXXScopeSpec &SS,
+ bool hasTemplateKeyword,
UnqualifiedId &Name,
- TypeTy *ObjectTypePtr,
+ ParsedType ObjectTypePtr,
bool EnteringContext,
TemplateTy &TemplateResult,
bool &MemberOfUnknownSpecialization) {
@@ -125,15 +135,21 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
return TNK_Non_template;
}
- QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+ QualType ObjectType = ObjectTypePtr.get();
LookupResult R(*this, TName, Name.getSourceRange().getBegin(),
LookupOrdinaryName);
- R.suppressDiagnostics();
LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
MemberOfUnknownSpecialization);
- if (R.empty() || R.isAmbiguous())
+ if (R.empty()) return TNK_Non_template;
+ if (R.isAmbiguous()) {
+ // Suppress diagnostics; we'll redo this lookup later.
+ R.suppressDiagnostics();
+
+ // FIXME: we might have ambiguous templates, in which case we
+ // should at least parse them properly!
return TNK_Non_template;
+ }
TemplateName Template;
TemplateNameKind TemplateKind;
@@ -144,20 +160,27 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
// template name in other ways.
Template = Context.getOverloadedTemplateName(R.begin(), R.end());
TemplateKind = TNK_Function_template;
+
+ // We'll do this lookup again later.
+ R.suppressDiagnostics();
} else {
TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
if (SS.isSet() && !SS.isInvalid()) {
NestedNameSpecifier *Qualifier
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- Template = Context.getQualifiedTemplateName(Qualifier, false, TD);
+ Template = Context.getQualifiedTemplateName(Qualifier,
+ hasTemplateKeyword, TD);
} else {
Template = TemplateName(TD);
}
- if (isa<FunctionTemplateDecl>(TD))
+ if (isa<FunctionTemplateDecl>(TD)) {
TemplateKind = TNK_Function_template;
- else {
+
+ // We'll do this lookup again later.
+ R.suppressDiagnostics();
+ } else {
assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD));
TemplateKind = TNK_Type_template;
}
@@ -238,13 +261,10 @@ void Sema::LookupTemplateName(LookupResult &Found,
// expression. If the identifier is not found, it is then looked up in
// the context of the entire postfix-expression and shall name a class
// or function template.
- //
- // FIXME: When we're instantiating a template, do we actually have to
- // look in the scope of the template? Seems fishy...
if (S) LookupName(Found, S);
ObjectTypeSearchedInScope = true;
}
- } else if (isDependent) {
+ } else if (isDependent && (!S || ObjectType.isNull())) {
// We cannot look into a dependent object type or nested nme
// specifier.
MemberOfUnknownSpecialization = true;
@@ -282,8 +302,11 @@ void Sema::LookupTemplateName(LookupResult &Found,
}
FilterAcceptableTemplateNames(Context, Found);
- if (Found.empty())
+ if (Found.empty()) {
+ if (isDependent)
+ MemberOfUnknownSpecialization = true;
return;
+ }
if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) {
// C++ [basic.lookup.classref]p1:
@@ -330,10 +353,9 @@ void Sema::LookupTemplateName(LookupResult &Found,
/// ActOnDependentIdExpression - Handle a dependent id-expression that
/// was just parsed. This is only possible with an explicit scope
/// specifier naming a dependent type.
-Sema::OwningExprResult
+ExprResult
Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
bool isAddressOfOperand,
const TemplateArgumentListInfo *TemplateArgs) {
NestedNameSpecifier *Qualifier
@@ -356,22 +378,21 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
/*Op*/ SourceLocation(),
Qualifier, SS.getRange(),
FirstQualifierInScope,
- Name, NameLoc,
+ NameInfo,
TemplateArgs));
}
- return BuildDependentDeclRefExpr(SS, Name, NameLoc, TemplateArgs);
+ return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs);
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
return Owned(DependentScopeDeclRefExpr::Create(Context,
static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
SS.getRange(),
- Name, NameLoc,
+ NameInfo,
TemplateArgs));
}
@@ -398,9 +419,9 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
/// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
/// the parameter D to reference the templated declaration and return a pointer
/// to the template declaration. Otherwise, do nothing to D and return null.
-TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
- if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D.getAs<Decl>())) {
- D = DeclPtrTy::make(Temp->getTemplatedDecl());
+TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
+ if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) {
+ D = Temp->getTemplatedDecl();
return Temp;
}
return 0;
@@ -424,8 +445,7 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
}
case ParsedTemplateArgument::Template: {
- TemplateName Template
- = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
+ TemplateName Template = Arg.getAsTemplate().get();
return TemplateArgumentLoc(TemplateArgument(Template),
Arg.getScopeSpec().getRange(),
Arg.getLocation());
@@ -454,14 +474,14 @@ void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
/// ParamName is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
-Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
- SourceLocation EllipsisLoc,
- SourceLocation KeyLoc,
- IdentifierInfo *ParamName,
- SourceLocation ParamNameLoc,
- unsigned Depth, unsigned Position,
- SourceLocation EqualLoc,
- TypeTy *DefaultArg) {
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+ SourceLocation EllipsisLoc,
+ SourceLocation KeyLoc,
+ IdentifierInfo *ParamName,
+ SourceLocation ParamNameLoc,
+ unsigned Depth, unsigned Position,
+ SourceLocation EqualLoc,
+ ParsedType DefaultArg) {
assert(S->isTemplateParamScope() &&
"Template type parameter not in template parameter scope!");
bool Invalid = false;
@@ -488,7 +508,7 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
if (ParamName) {
// Add the template parameter into the current scope.
- S->AddDecl(DeclPtrTy::make(Param));
+ S->AddDecl(Param);
IdResolver.AddDecl(Param);
}
@@ -504,19 +524,19 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
// template-parameter that is not a template parameter pack.
if (Ellipsis) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
- return DeclPtrTy::make(Param);
+ return Param;
}
// Check the template argument itself.
if (CheckTemplateArgument(Param, DefaultTInfo)) {
Param->setInvalidDecl();
- return DeclPtrTy::make(Param);;
+ return Param;
}
Param->setDefaultArgument(DefaultTInfo, false);
}
- return DeclPtrTy::make(Param);
+ return Param;
}
/// \brief Check that the type of a non-type template parameter is
@@ -542,9 +562,7 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
// -- integral or enumeration type,
if (T->isIntegralOrEnumerationType() ||
// -- pointer to object or pointer to function,
- (T->isPointerType() &&
- (T->getAs<PointerType>()->getPointeeType()->isObjectType() ||
- T->getAs<PointerType>()->getPointeeType()->isFunctionType())) ||
+ T->isPointerType() ||
// -- reference to object or reference to function,
T->isReferenceType() ||
// -- pointer to member.
@@ -571,11 +589,11 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
return QualType();
}
-Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
- ExprArg DefaultArg) {
+Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+ unsigned Depth,
+ unsigned Position,
+ SourceLocation EqualLoc,
+ Expr *Default) {
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType T = TInfo->getType();
@@ -608,35 +626,35 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
if (D.getIdentifier()) {
// Add the template parameter into the current scope.
- S->AddDecl(DeclPtrTy::make(Param));
+ S->AddDecl(Param);
IdResolver.AddDecl(Param);
}
// Check the well-formedness of the default template argument, if provided.
- if (Expr *Default = static_cast<Expr *>(DefaultArg.get())) {
+ if (Default) {
TemplateArgument Converted;
if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
Param->setInvalidDecl();
- return DeclPtrTy::make(Param);;
+ return Param;
}
- Param->setDefaultArgument(DefaultArg.takeAs<Expr>(), false);
+ Param->setDefaultArgument(Default, false);
}
- return DeclPtrTy::make(Param);
+ return Param;
}
/// ActOnTemplateTemplateParameter - Called when a C++ template template
/// parameter (e.g. T in template <template <typename> class T> class array)
/// has been parsed. S is the current scope.
-Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
- SourceLocation TmpLoc,
- TemplateParamsTy *Params,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- unsigned Depth,
- unsigned Position,
- SourceLocation EqualLoc,
+Decl *Sema::ActOnTemplateTemplateParameter(Scope* S,
+ SourceLocation TmpLoc,
+ TemplateParamsTy *Params,
+ IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ unsigned Depth,
+ unsigned Position,
+ SourceLocation EqualLoc,
const ParsedTemplateArgument &Default) {
assert(S->isTemplateParamScope() &&
"Template template parameter not in template parameter scope!");
@@ -644,13 +662,14 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
// Construct the parameter object.
TemplateTemplateParmDecl *Param =
TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
- TmpLoc, Depth, Position, Name,
+ NameLoc.isInvalid()? TmpLoc : NameLoc,
+ Depth, Position, Name,
(TemplateParameterList*)Params);
// If the template template parameter has a name, then link the identifier
// into the scope and lookup mechanisms.
if (Name) {
- S->AddDecl(DeclPtrTy::make(Param));
+ S->AddDecl(Param);
IdResolver.AddDecl(Param);
}
@@ -667,13 +686,13 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
if (DefaultArg.getArgument().getAsTemplate().isNull()) {
Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
<< DefaultArg.getSourceRange();
- return DeclPtrTy::make(Param);
+ return Param;
}
Param->setDefaultArgument(DefaultArg, false);
}
- return DeclPtrTy::make(Param);
+ return Param;
}
/// ActOnTemplateParameterList - Builds a TemplateParameterList that
@@ -683,7 +702,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth,
SourceLocation ExportLoc,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- DeclPtrTy *Params, unsigned NumParams,
+ Decl **Params, unsigned NumParams,
SourceLocation RAngleLoc) {
if (ExportLoc.isValid())
Diag(ExportLoc, diag::warn_template_export_unsupported);
@@ -699,7 +718,7 @@ static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
SS.getRange());
}
-Sema::DeclResult
+DeclResult
Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
@@ -922,7 +941,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Friend templates are visible in fairly strange ways.
if (!CurContext->isDependentContext()) {
- DeclContext *DC = SemanticContext->getLookupContext();
+ DeclContext *DC = SemanticContext->getRedeclContext();
DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false);
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
PushOnScopeChains(NewTemplate, EnclosingScope,
@@ -941,7 +960,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
NewTemplate->setInvalidDecl();
NewClass->setInvalidDecl();
}
- return DeclPtrTy::make(NewTemplate);
+ return NewTemplate;
}
/// \brief Diagnose the presence of a default template argument on a
@@ -1102,7 +1121,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
DiagnoseDefaultTemplateArgument(*this, TPC,
NewNonTypeParm->getLocation(),
NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
- NewNonTypeParm->getDefaultArgument()->Destroy(Context);
NewNonTypeParm->removeDefaultArgument();
}
@@ -1477,14 +1495,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
= dyn_cast<ClassTemplateDecl>(Template)) {
// Find the class template specialization declaration that
// corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+ = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(), InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
// specialization. Create the canonical declaration and add it to
@@ -1495,7 +1509,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
ClassTemplate->getLocation(),
ClassTemplate,
Converted, 0);
- ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
+ ClassTemplate->AddSpecialization(Decl, InsertPos);
Decl->setLexicalDeclContext(CurContext);
}
@@ -1510,7 +1524,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
}
-Action::TypeResult
+TypeResult
Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
@@ -1536,15 +1550,15 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
- return CreateLocInfoType(Result, DI).getAsOpaquePtr();
+ return CreateParsedType(Result, DI);
}
-Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
- TagUseKind TUK,
- DeclSpec::TST TagSpec,
- SourceLocation TagLoc) {
+TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
+ TagUseKind TUK,
+ TypeSpecifierType TagSpec,
+ SourceLocation TagLoc) {
if (TypeResult.isInvalid())
- return Sema::TypeResult();
+ return ::TypeResult();
// FIXME: preserve source info, ideally without copying the DI.
TypeSourceInfo *DI;
@@ -1571,10 +1585,10 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
= TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
- return ElabType.getAsOpaquePtr();
+ return ParsedType::make(ElabType);
}
-Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
+ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
LookupResult &R,
bool RequiresADL,
const TemplateArgumentListInfo &TemplateArgs) {
@@ -1603,7 +1617,7 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
UnresolvedLookupExpr *ULE
= UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
Qualifier, QualifierRange,
- R.getLookupName(), R.getNameLoc(),
+ R.getLookupNameInfo(),
RequiresADL, TemplateArgs,
R.begin(), R.end());
@@ -1611,19 +1625,18 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
}
// We actually only call this from template instantiation.
-Sema::OwningExprResult
+ExprResult
Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo &TemplateArgs) {
DeclContext *DC;
if (!(DC = computeDeclContext(SS, false)) ||
DC->isDependentContext() ||
RequireCompleteDeclContext(SS, DC))
- return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
+ return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs);
bool MemberOfUnknownSpecialization;
- LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
MemberOfUnknownSpecialization);
@@ -1631,14 +1644,15 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
return ExprError();
if (R.empty()) {
- Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
- << Name << SS.getRange();
+ Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
+ << NameInfo.getName() << SS.getRange();
return ExprError();
}
if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
- Diag(NameLoc, diag::err_template_kw_refers_to_class_template)
- << (NestedNameSpecifier*) SS.getScopeRep() << Name << SS.getRange();
+ Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
+ << (NestedNameSpecifier*) SS.getScopeRep()
+ << NameInfo.getName() << SS.getRange();
Diag(Temp->getLocation(), diag::note_referenced_class_template);
return ExprError();
}
@@ -1657,7 +1671,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
SourceLocation TemplateKWLoc,
CXXScopeSpec &SS,
UnqualifiedId &Name,
- TypeTy *ObjectType,
+ ParsedType ObjectType,
bool EnteringContext,
TemplateTy &Result) {
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
@@ -1669,7 +1683,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
if (SS.isSet())
LookupCtx = computeDeclContext(SS, EnteringContext);
if (!LookupCtx && ObjectType)
- LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+ LookupCtx = computeDeclContext(ObjectType.get());
if (LookupCtx) {
// C++0x [temp.names]p5:
// If a name prefixed by the keyword template is not the name of
@@ -1688,8 +1702,8 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
// "template" keyword is now permitted). We follow the C++0x
// rules, even in C++03 mode with a warning, retroactively applying the DR.
bool MemberOfUnknownSpecialization;
- TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType,
- EnteringContext, Result,
+ TemplateNameKind TNK = isTemplateName(0, SS, TemplateKWLoc.isValid(), Name,
+ ObjectType, EnteringContext, Result,
MemberOfUnknownSpecialization);
if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
isa<CXXRecordDecl>(LookupCtx) &&
@@ -1698,7 +1712,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
} else if (TNK == TNK_Non_template) {
Diag(Name.getSourceRange().getBegin(),
diag::err_template_kw_refers_to_non_template)
- << GetNameFromUnqualifiedId(Name)
+ << GetNameFromUnqualifiedId(Name).getName()
<< Name.getSourceRange()
<< TemplateKWLoc;
return TNK_Non_template;
@@ -1731,7 +1745,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
Diag(Name.getSourceRange().getBegin(),
diag::err_template_kw_refers_to_non_template)
- << GetNameFromUnqualifiedId(Name)
+ << GetNameFromUnqualifiedId(Name).getName()
<< Name.getSourceRange()
<< TemplateKWLoc;
return TNK_Non_template;
@@ -1856,7 +1870,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
/// parameters that precede \p Param in the template parameter list.
///
/// \returns the substituted template argument, or NULL if an error occurred.
-static Sema::OwningExprResult
+static ExprResult
SubstDefaultTemplateArgument(Sema &SemaRef,
TemplateDecl *Template,
SourceLocation TemplateLoc,
@@ -1952,7 +1966,7 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
if (!NonTypeParm->hasDefaultArgument())
return TemplateArgumentLoc();
- OwningExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
+ ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
TemplateLoc,
RAngleLoc,
NonTypeParm,
@@ -2052,12 +2066,15 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
// We have a template argument such as \c T::template X, which we
// parsed as a template template argument. However, since we now
// know that we need a non-type template argument, convert this
- // template name into an expression.
+ // template name into an expression.
+
+ DeclarationNameInfo NameInfo(DTN->getIdentifier(),
+ Arg.getTemplateNameLoc());
+
Expr *E = DependentScopeDeclRefExpr::Create(Context,
DTN->getQualifier(),
Arg.getTemplateQualifierRange(),
- DTN->getIdentifier(),
- Arg.getTemplateNameLoc());
+ NameInfo);
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
@@ -2272,7 +2289,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
break;
}
- Sema::OwningExprResult E = SubstDefaultTemplateArgument(*this, Template,
+ ExprResult E = SubstDefaultTemplateArgument(*this, Template,
TemplateLoc,
RAngleLoc,
NTTP,
@@ -2330,31 +2347,33 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
assert(ArgInfo && "invalid TypeSourceInfo");
QualType Arg = ArgInfo->getType();
- // C++ [temp.arg.type]p2:
+ // C++03 [temp.arg.type]p2:
// A local type, a type with no linkage, an unnamed type or a type
// compounded from any of these types shall not be used as a
// template-argument for a template type-parameter.
- //
- // FIXME: Perform the unnamed type check.
+ // C++0x allows these, and even in C++03 we allow them as an extension with
+ // a warning.
SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
- const TagType *Tag = 0;
- if (const EnumType *EnumT = Arg->getAs<EnumType>())
- Tag = EnumT;
- else if (const RecordType *RecordT = Arg->getAs<RecordType>())
- Tag = RecordT;
- if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
- SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
- return Diag(SR.getBegin(), diag::err_template_arg_local_type)
- << QualType(Tag, 0) << SR;
- } else if (Tag && !Tag->getDecl()->getDeclName() &&
- !Tag->getDecl()->getTypedefForAnonDecl()) {
- Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR;
- Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
- return true;
- } else if (Arg->isVariablyModifiedType()) {
- Diag(SR.getBegin(), diag::err_variably_modified_template_arg)
- << Arg;
- return true;
+ if (!LangOpts.CPlusPlus0x) {
+ const TagType *Tag = 0;
+ if (const EnumType *EnumT = Arg->getAs<EnumType>())
+ Tag = EnumT;
+ else if (const RecordType *RecordT = Arg->getAs<RecordType>())
+ Tag = RecordT;
+ if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
+ SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
+ Diag(SR.getBegin(), diag::ext_template_arg_local_type)
+ << QualType(Tag, 0) << SR;
+ } else if (Tag && !Tag->getDecl()->getDeclName() &&
+ !Tag->getDecl()->getTypedefForAnonDecl()) {
+ Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
+ Diag(Tag->getDecl()->getLocation(),
+ diag::note_template_unnamed_type_here);
+ }
+ }
+
+ if (Arg->isVariablyModifiedType()) {
+ return Diag(SR.getBegin(), diag::err_variably_modified_template_arg) << Arg;
} else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) {
return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR;
}
@@ -2406,7 +2425,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
bool AddressTaken = false;
SourceLocation AddrOpLoc;
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
- if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+ if (UnOp->getOpcode() == UO_AddrOf) {
DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
AddressTaken = true;
AddrOpLoc = UnOp->getOperatorLoc();
@@ -2653,7 +2672,7 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
// A pointer-to-member constant written &Class::member.
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
- if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+ if (UnOp->getOpcode() == UO_AddrOf) {
DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
if (DRE && !DRE->getQualifier())
DRE = 0;
@@ -2788,7 +2807,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
} else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
!ParamType->isEnumeralType()) {
// This is an integral promotion or conversion.
- ImpCastExprToType(Arg, ParamType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Arg, ParamType, CK_IntegralCast);
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
@@ -2909,8 +2928,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
Arg, Converted);
if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType())) {
- ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
- Arg->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
} else if (!Context.hasSameUnqualifiedType(ArgType,
ParamType.getNonReferenceType())) {
// We can't perform this conversion.
@@ -2929,7 +2947,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// object, qualification conversions (4.4) and the
// array-to-pointer conversion (4.2) are applied.
// C++0x also allows a value of std::nullptr_t.
- assert(ParamType->getAs<PointerType>()->getPointeeType()->isObjectType() &&
+ assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
"Only object pointers allowed here");
return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
@@ -2944,7 +2962,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// identical) type of the template-argument. The
// template-parameter is bound directly to the
// template-argument, which must be an lvalue.
- assert(ParamRefType->getPointeeType()->isObjectType() &&
+ assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() &&
"Only object references allowed here");
if (Arg->getType() == Context.OverloadTy) {
@@ -2973,8 +2991,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
// Types match exactly: nothing more to do here.
} else if (IsQualificationConversion(ArgType, ParamType)) {
- ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
- Arg->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
@@ -3033,7 +3050,7 @@ bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
/// declaration and the type of its corresponding non-type template
/// parameter, produce an expression that properly refers to that
/// declaration.
-Sema::OwningExprResult
+ExprResult
Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
QualType ParamType,
SourceLocation Loc) {
@@ -3052,17 +3069,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
QualType ClassType
= Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
NestedNameSpecifier *Qualifier
- = NestedNameSpecifier::Create(Context, 0, false, ClassType.getTypePtr());
+ = NestedNameSpecifier::Create(Context, 0, false,
+ ClassType.getTypePtr());
CXXScopeSpec SS;
SS.setScopeRep(Qualifier);
- OwningExprResult RefExpr = BuildDeclRefExpr(VD,
+ ExprResult RefExpr = BuildDeclRefExpr(VD,
VD->getType().getNonReferenceType(),
Loc,
&SS);
if (RefExpr.isInvalid())
return ExprError();
- RefExpr = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+ RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
// We might need to perform a trailing qualification conversion, since
// the element type on the parameter could be more qualified than the
@@ -3070,8 +3088,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
ParamType.getUnqualifiedType())) {
Expr *RefE = RefExpr.takeAs<Expr>();
- ImpCastExprToType(RefE, ParamType.getUnqualifiedType(),
- CastExpr::CK_NoOp);
+ ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
RefExpr = Owned(RefE);
}
@@ -3086,7 +3103,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
if (ParamType->isPointerType()) {
// When the non-type template parameter is a pointer, take the
// address of the declaration.
- OwningExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
+ ExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
if (RefExpr.isInvalid())
return ExprError();
@@ -3103,7 +3120,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
}
// Take the address of everything else
- return CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+ return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
}
// If the non-type template parameter has reference type, qualify the
@@ -3122,7 +3139,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
/// This routine takes care of the mapping from an integral template
/// argument (which may have any integral type) to the appropriate
/// literal value.
-Sema::OwningExprResult
+ExprResult
Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
SourceLocation Loc) {
assert(Arg.getKind() == TemplateArgument::Integral &&
@@ -3140,7 +3157,7 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
T,
Loc));
- return Owned(new (Context) IntegerLiteral(*Arg.getAsIntegral(), T, Loc));
+ return Owned(IntegerLiteral::Create(Context, *Arg.getAsIntegral(), T, Loc));
}
@@ -3401,7 +3418,7 @@ static bool CheckTemplateSpecializationScope(Sema &S,
// the explicit specialization was declared, or in a namespace
// that encloses the one in which the explicit specialization was
// declared.
- if (S.CurContext->getLookupContext()->isFunctionOrMethod()) {
+ if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) {
S.Diag(Loc, diag::err_template_spec_decl_function_scope)
<< Specialized;
return true;
@@ -3426,8 +3443,8 @@ static bool CheckTemplateSpecializationScope(Sema &S,
getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
// There is no prior declaration of this entity, so this
// specialization must be in the same context as the template
- // itself.
- if (!DC->Equals(SpecializedContext)) {
+ // itself, or in the enclosing namespace set.
+ if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
if (isa<TranslationUnitDecl>(SpecializedContext))
S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
<< EntityKind << Specialized;
@@ -3597,7 +3614,7 @@ static NamedDecl *getPreviousDecl(NamedDecl *ND) {
return 0;
}
-Sema::DeclResult
+DeclResult
Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TagUseKind TUK,
SourceLocation KWLoc,
@@ -3666,7 +3683,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
diag::err_default_arg_in_partial_spec)
<< DefArg->getSourceRange();
NTTP->removeDefaultArgument();
- DefArg->Destroy(Context);
}
} else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
@@ -3729,7 +3745,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// Find the class template (partial) specialization declaration that
// corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
if (isPartialSpecialization) {
bool MirrorsPrimaryTemplate;
if (CheckClassTemplatePartialSpecializationArgs(
@@ -3762,30 +3777,22 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< ClassTemplate->getDeclName();
isPartialSpecialization = false;
- } else {
- // FIXME: Template parameter list matters, too
- ClassTemplatePartialSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- Context);
}
}
-
- if (!isPartialSpecialization)
- ClassTemplateSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- Context);
+
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl = 0;
if (isPartialSpecialization)
+ // FIXME: Template parameter list matters, too
PrevDecl
- = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(),
+ InsertPos);
else
PrevDecl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+ = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(), InsertPos);
ClassTemplateSpecializationDecl *Specialization = 0;
@@ -3823,7 +3830,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
ClassTemplatePartialSpecializationDecl *PrevPartial
= cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
- : ClassTemplate->getPartialSpecializations().size();
+ : ClassTemplate->getNextPartialSpecSequenceNumber();
ClassTemplatePartialSpecializationDecl *Partial
= ClassTemplatePartialSpecializationDecl::Create(Context, Kind,
ClassTemplate->getDeclContext(),
@@ -3836,18 +3843,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
PrevPartial,
SequenceNumber);
SetNestedNameSpecifier(Partial, SS);
- if (NumMatchedTemplateParamLists > 0) {
+ if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
Partial->setTemplateParameterListsInfo(Context,
NumMatchedTemplateParamLists,
(TemplateParameterList**) TemplateParameterLists.release());
}
- if (PrevPartial) {
- ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
- ClassTemplate->getPartialSpecializations().GetOrInsertNode(Partial);
- } else {
- ClassTemplate->getPartialSpecializations().InsertNode(Partial, InsertPos);
- }
+ if (!PrevPartial)
+ ClassTemplate->AddPartialSpecialization(Partial, InsertPos);
Specialization = Partial;
// If we are providing an explicit specialization of a member class
@@ -3883,7 +3886,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
else
Diag(Param->getLocation(),
diag::note_partial_spec_unused_parameter)
- << std::string("<anonymous>");
+ << "<anonymous>";
}
}
}
@@ -3898,19 +3901,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
Converted,
PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
- if (NumMatchedTemplateParamLists > 0) {
+ if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
Specialization->setTemplateParameterListsInfo(Context,
NumMatchedTemplateParamLists,
(TemplateParameterList**) TemplateParameterLists.release());
}
- if (PrevDecl) {
- ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
- ClassTemplate->getSpecializations().GetOrInsertNode(Specialization);
- } else {
- ClassTemplate->getSpecializations().InsertNode(Specialization,
- InsertPos);
- }
+ if (!PrevDecl)
+ ClassTemplate->AddSpecialization(Specialization, InsertPos);
CanonType = Context.getTypeDeclType(Specialization);
}
@@ -4004,20 +4002,18 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// context. However, specializations are not found by name lookup.
CurContext->addDecl(Specialization);
}
- return DeclPtrTy::make(Specialization);
+ return Specialization;
}
-Sema::DeclPtrTy
-Sema::ActOnTemplateDeclarator(Scope *S,
+Decl *Sema::ActOnTemplateDeclarator(Scope *S,
MultiTemplateParamsArg TemplateParameterLists,
- Declarator &D) {
+ Declarator &D) {
return HandleDeclarator(S, D, move(TemplateParameterLists), false);
}
-Sema::DeclPtrTy
-Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
MultiTemplateParamsArg TemplateParameterLists,
- Declarator &D) {
+ Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
"Not a function declarator!");
@@ -4029,22 +4025,22 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
Scope *ParentScope = FnBodyScope->getParent();
- DeclPtrTy DP = HandleDeclarator(ParentScope, D,
- move(TemplateParameterLists),
- /*IsFunctionDefinition=*/true);
+ Decl *DP = HandleDeclarator(ParentScope, D,
+ move(TemplateParameterLists),
+ /*IsFunctionDefinition=*/true);
if (FunctionTemplateDecl *FunctionTemplate
- = dyn_cast_or_null<FunctionTemplateDecl>(DP.getAs<Decl>()))
+ = dyn_cast_or_null<FunctionTemplateDecl>(DP))
return ActOnStartOfFunctionDef(FnBodyScope,
- DeclPtrTy::make(FunctionTemplate->getTemplatedDecl()));
- if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP.getAs<Decl>()))
- return ActOnStartOfFunctionDef(FnBodyScope, DeclPtrTy::make(Function));
- return DeclPtrTy();
+ FunctionTemplate->getTemplatedDecl());
+ if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP))
+ return ActOnStartOfFunctionDef(FnBodyScope, Function);
+ return 0;
}
/// \brief Strips various properties off an implicit instantiation
/// that has just been explicitly specialized.
static void StripImplicitInstantiation(NamedDecl *D) {
- D->invalidateAttrs();
+ D->dropAttrs();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
FD->setInlineSpecified(false);
@@ -4241,12 +4237,13 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
LookupResult &Previous) {
// Remove anything from Previous that isn't a function template in
// the correct context.
- DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+ DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
LookupResult::Filter F = Previous.makeFilter();
while (F.hasNext()) {
NamedDecl *D = F.next()->getUnderlyingDecl();
if (!isa<FunctionTemplateDecl>(D) ||
- !FDLookupContext->Equals(D->getDeclContext()->getLookupContext()))
+ !FDLookupContext->InEnclosingNamespaceSetOf(
+ D->getDeclContext()->getRedeclContext()))
F.erase();
}
F.done();
@@ -4285,14 +4282,15 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
// explicit function template specialization.
UnresolvedSet<8> Candidates;
- DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+ DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
I != E; ++I) {
NamedDecl *Ovl = (*I)->getUnderlyingDecl();
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
// Only consider templates found within the same semantic lookup scope as
// FD.
- if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext()))
+ if (!FDLookupContext->InEnclosingNamespaceSetOf(
+ Ovl->getDeclContext()->getRedeclContext()))
continue;
// C++ [temp.expl.spec]p11:
@@ -4373,8 +4371,10 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
// Mark the prior declaration as an explicit specialization, so that later
// clients know that this is an explicit specialization.
- if (!isFriend)
+ if (!isFriend) {
SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
+ MarkUnusedFileScopedDecl(Specialization);
+ }
// Turn the given function declaration into a function template
// specialization, with the template arguments from the previous
@@ -4527,6 +4527,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
cast<CXXMethodDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
+ MarkUnusedFileScopedDecl(InstantiationFunction);
} else if (isa<VarDecl>(Member)) {
VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
if (InstantiationVar->getTemplateSpecializationKind() ==
@@ -4539,6 +4540,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
cast<VarDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
+ MarkUnusedFileScopedDecl(InstantiationVar);
} else {
assert(isa<CXXRecordDecl>(Member) && "Only member classes remain");
CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
@@ -4567,9 +4569,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
SourceLocation InstLoc,
bool WasQualifiedName) {
- DeclContext *ExpectedContext
- = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
- DeclContext *CurContext = S.CurContext->getLookupContext();
+ DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext();
+ DeclContext *CurContext = S.CurContext->getRedeclContext();
if (CurContext->isRecord()) {
S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
@@ -4583,8 +4584,8 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
//
// This is DR275, which we do not retroactively apply to C++98/03.
if (S.getLangOptions().CPlusPlus0x &&
- !CurContext->Encloses(ExpectedContext)) {
- if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ExpectedContext))
+ !CurContext->Encloses(OrigContext)) {
+ if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext))
S.Diag(InstLoc,
S.getLangOptions().CPlusPlus0x?
diag::err_explicit_instantiation_out_of_scope
@@ -4599,7 +4600,7 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
return false;
}
-
+
// C++0x [temp.explicit]p2:
// If the name declared in the explicit instantiation is an unqualified
// name, the explicit instantiation shall appear in the namespace where
@@ -4607,15 +4608,15 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
// namespace from its enclosing namespace set.
if (WasQualifiedName)
return false;
-
- if (CurContext->Equals(ExpectedContext))
+
+ if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
return false;
-
+
S.Diag(InstLoc,
S.getLangOptions().CPlusPlus0x?
diag::err_explicit_instantiation_unqualified_wrong_namespace
: diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
- << D << ExpectedContext;
+ << D << OrigContext;
S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
return false;
}
@@ -4642,7 +4643,7 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
}
// Explicit instantiation of a class template specialization
-Sema::DeclResult
+DeclResult
Sema::ActOnExplicitInstantiation(Scope *S,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
@@ -4703,14 +4704,10 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Find the class template specialization declaration that
// corresponds to these arguments.
- llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+ = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(), InsertPos);
TemplateSpecializationKind PrevDecl_TSK
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
@@ -4733,7 +4730,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
PrevDecl, PrevDecl_TSK,
PrevDecl->getPointOfInstantiation(),
HasNoEffect))
- return DeclPtrTy::make(PrevDecl);
+ return PrevDecl;
// Even though HasNoEffect == true means that this explicit instantiation
// has no effect on semantics, we go on to put its syntax in the AST.
@@ -4763,15 +4760,9 @@ Sema::ActOnExplicitInstantiation(Scope *S,
Converted, PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
- if (!HasNoEffect) {
- if (PrevDecl) {
- // Remove the previous declaration from the folding set, since we want
- // to introduce a new declaration.
- ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
- ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
- }
+ if (!HasNoEffect && !PrevDecl) {
// Insert the new specialization.
- ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos);
+ ClassTemplate->AddSpecialization(Specialization, InsertPos);
}
}
@@ -4803,7 +4794,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
if (HasNoEffect) {
// Set the template specialization kind.
Specialization->setTemplateSpecializationKind(TSK);
- return DeclPtrTy::make(Specialization);
+ return Specialization;
}
// C++ [temp.explicit]p3:
@@ -4840,11 +4831,11 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Set the template specialization kind.
Specialization->setTemplateSpecializationKind(TSK);
- return DeclPtrTy::make(Specialization);
+ return Specialization;
}
// Explicit instantiation of a member class of a class template.
-Sema::DeclResult
+DeclResult
Sema::ActOnExplicitInstantiation(Scope *S,
SourceLocation ExternLoc,
SourceLocation TemplateLoc,
@@ -4857,16 +4848,16 @@ Sema::ActOnExplicitInstantiation(Scope *S,
bool Owned = false;
bool IsDependent = false;
- DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TUK_Reference,
- KWLoc, SS, Name, NameLoc, Attr, AS_none,
- MultiTemplateParamsArg(*this, 0, 0),
- Owned, IsDependent);
+ Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
+ KWLoc, SS, Name, NameLoc, Attr, AS_none,
+ MultiTemplateParamsArg(*this, 0, 0),
+ Owned, IsDependent);
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
if (!TagD)
return true;
- TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+ TagDecl *Tag = cast<TagDecl>(TagD);
if (Tag->isEnum()) {
Diag(TemplateLoc, diag::err_explicit_instantiation_enum)
<< Context.getTypeDeclType(Tag);
@@ -4969,12 +4960,14 @@ Sema::ActOnExplicitInstantiation(Scope *S,
return TagD;
}
-Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- Declarator &D) {
+DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
+ SourceLocation ExternLoc,
+ SourceLocation TemplateLoc,
+ Declarator &D) {
// Explicit instantiations always require a name.
- DeclarationName Name = GetNameForDeclarator(D);
+ // TODO: check if/when DNInfo should replace Name.
+ DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+ DeclarationName Name = NameInfo.getName();
if (!Name) {
if (!D.isInvalidType())
Diag(D.getDeclSpec().getSourceRange().getBegin(),
@@ -5024,7 +5017,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
- LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
+ LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
LookupParsedName(Previous, S, &D.getCXXScopeSpec());
if (!R->isFunctionType()) {
@@ -5081,16 +5074,15 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
HasNoEffect))
return true;
if (HasNoEffect)
- return DeclPtrTy();
+ return (Decl*) 0;
// Instantiate static data member.
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (TSK == TSK_ExplicitInstantiationDefinition)
- InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false,
- /*DefinitionRequired=*/true);
+ InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
// FIXME: Create an ExplicitInstantiation node?
- return DeclPtrTy();
+ return (Decl*) 0;
}
// If the declarator is a template-id, translate the parser's template
@@ -5188,14 +5180,13 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// FIXME: We may still want to build some representation of this
// explicit specialization.
if (HasNoEffect)
- return DeclPtrTy();
+ return (Decl*) 0;
}
Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (TSK == TSK_ExplicitInstantiationDefinition)
- InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization,
- false, /*DefinitionRequired=*/true);
+ InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
// C++0x [temp.explicit]p2:
// If the explicit instantiation is for a member function, a member class
@@ -5219,10 +5210,10 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
D.getCXXScopeSpec().isSet());
// FIXME: Create some kind of ExplicitInstantiationDecl here.
- return DeclPtrTy();
+ return (Decl*) 0;
}
-Sema::TypeResult
+TypeResult
Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
const CXXScopeSpec &SS, IdentifierInfo *Name,
SourceLocation TagLoc, SourceLocation NameLoc) {
@@ -5243,10 +5234,10 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
- return Context.getDependentNameType(Kwd, NNS, Name).getAsOpaquePtr();
+ return ParsedType::make(Context.getDependentNameType(Kwd, NNS, Name));
}
-Sema::TypeResult
+TypeResult
Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
const CXXScopeSpec &SS, const IdentifierInfo &II,
SourceLocation IdLoc) {
@@ -5278,13 +5269,13 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
}
- return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+ return CreateParsedType(T, TSI);
}
-Sema::TypeResult
+TypeResult
Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
const CXXScopeSpec &SS, SourceLocation TemplateLoc,
- TypeTy *Ty) {
+ ParsedType Ty) {
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
!getLangOptions().CPlusPlus0x)
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
@@ -5292,8 +5283,6 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
TypeSourceInfo *InnerTSI = 0;
QualType T = GetTypeFromParser(Ty, &InnerTSI);
- NestedNameSpecifier *NNS
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
assert(isa<TemplateSpecializationType>(T) &&
"Expected a template specialization type");
@@ -5310,13 +5299,14 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
else
Builder.push<TemplateSpecializationTypeLoc>(T).initialize(TemplateLoc);
- T = Context.getElaboratedType(ETK_Typename, NNS, T);
+ /* Note: NNS already embedded in template specialization type T. */
+ T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(SS.getRange());
TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
- return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+ return CreateParsedType(T, TSI);
}
// TODO: it's really silly that we make a template specialization
@@ -5325,7 +5315,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
DependentTemplateName *DTN =
TST->getTemplateName().getAsDependentTemplateName();
assert(DTN && "dependent template has non-dependent name?");
- T = Context.getDependentTemplateSpecializationType(ETK_Typename, NNS,
+ assert(DTN->getQualifier()
+ == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+ T = Context.getDependentTemplateSpecializationType(ETK_Typename,
+ DTN->getQualifier(),
DTN->getIdentifier(),
TST->getNumArgs(),
TST->getArgs());
@@ -5344,7 +5337,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
}
TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(SS.getRange());
- return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+ return CreateParsedType(T, TSI);
}
/// \brief Build the type that describes a C++ typename specifier,
@@ -5463,15 +5456,6 @@ namespace {
this->Loc = Loc;
this->Entity = Entity;
}
-
- /// \brief Transforms an expression by returning the expression itself
- /// (an identity function).
- ///
- /// FIXME: This is completely unsafe; we will need to actually clone the
- /// expressions.
- Sema::OwningExprResult TransformExpr(Expr *E) {
- return getSema().Owned(E->Retain());
- }
};
}
@@ -5511,6 +5495,12 @@ TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
return Rebuilder.TransformType(T);
}
+ExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) {
+ CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(),
+ DeclarationName());
+ return Rebuilder.TransformExpr(E);
+}
+
bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
if (SS.isInvalid()) return true;
diff --git a/lib/Sema/SemaTemplate.h b/lib/Sema/SemaTemplate.h
deleted file mode 100644
index b3f46519ab7f..000000000000
--- a/lib/Sema/SemaTemplate.h
+++ /dev/null
@@ -1,151 +0,0 @@
-//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
-//
-// This file provides types used in the semantic analysis of C++ templates.
-//
-//===----------------------------------------------------------------------===/
-#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
-#define LLVM_CLANG_SEMA_TEMPLATE_H
-
-#include "clang/AST/DeclTemplate.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-
-namespace clang {
- /// \brief Data structure that captures multiple levels of template argument
- /// lists for use in template instantiation.
- ///
- /// Multiple levels of template arguments occur when instantiating the
- /// definitions of member templates. For example:
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<T Value>
- /// struct Y {
- /// void f();
- /// };
- /// };
- /// \endcode
- ///
- /// When instantiating X<int>::Y<17>::f, the multi-level template argument
- /// list will contain a template argument list (int) at depth 0 and a
- /// template argument list (17) at depth 1.
- class MultiLevelTemplateArgumentList {
- public:
- typedef std::pair<const TemplateArgument *, unsigned> ArgList;
-
- private:
- /// \brief The template argument lists, stored from the innermost template
- /// argument list (first) to the outermost template argument list (last).
- llvm::SmallVector<ArgList, 4> TemplateArgumentLists;
-
- public:
- /// \brief Construct an empty set of template argument lists.
- MultiLevelTemplateArgumentList() { }
-
- /// \brief Construct a single-level template argument list.
- explicit
- MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
- addOuterTemplateArguments(&TemplateArgs);
- }
-
- /// \brief Determine the number of levels in this template argument
- /// list.
- unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
-
- /// \brief Retrieve the template argument at a given depth and index.
- const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
- assert(Depth < TemplateArgumentLists.size());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second);
- return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index];
- }
-
- /// \brief Determine whether there is a non-NULL template argument at the
- /// given depth and index.
- ///
- /// There must exist a template argument list at the given depth.
- bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
- assert(Depth < TemplateArgumentLists.size());
-
- if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second)
- return false;
-
- return !(*this)(Depth, Index).isNull();
- }
-
- /// \brief Add a new outermost level to the multi-level template argument
- /// list.
- void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
- TemplateArgumentLists.push_back(
- ArgList(TemplateArgs->getFlatArgumentList(),
- TemplateArgs->flat_size()));
- }
-
- /// \brief Add a new outmost level to the multi-level template argument
- /// list.
- void addOuterTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs) {
- TemplateArgumentLists.push_back(ArgList(Args, NumArgs));
- }
-
- /// \brief Retrieve the innermost template argument list.
- const ArgList &getInnermost() const {
- return TemplateArgumentLists.front();
- }
- };
-
- /// \brief The context in which partial ordering of function templates occurs.
- enum TemplatePartialOrderingContext {
- /// \brief Partial ordering of function templates for a function call.
- TPOC_Call,
- /// \brief Partial ordering of function templates for a call to a
- /// conversion function.
- TPOC_Conversion,
- /// \brief Partial ordering of function templates in other contexts, e.g.,
- /// taking the address of a function template or matching a function
- /// template specialization to a function template.
- TPOC_Other
- };
-
- /// \brief Captures a template argument whose value has been deduced
- /// via c++ template argument deduction.
- class DeducedTemplateArgument : public TemplateArgument {
- /// \brief For a non-type template argument, whether the value was
- /// deduced from an array bound.
- bool DeducedFromArrayBound;
-
- public:
- DeducedTemplateArgument()
- : TemplateArgument(), DeducedFromArrayBound(false) { }
-
- DeducedTemplateArgument(const TemplateArgument &Arg,
- bool DeducedFromArrayBound = false)
- : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
-
- /// \brief Construct an integral non-type template argument that
- /// has been deduced, possible from an array bound.
- DeducedTemplateArgument(const llvm::APSInt &Value,
- QualType ValueType,
- bool DeducedFromArrayBound)
- : TemplateArgument(Value, ValueType),
- DeducedFromArrayBound(DeducedFromArrayBound) { }
-
- /// \brief For a non-type template argument, determine whether the
- /// template argument was deduced from an array bound.
- bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
-
- /// \brief Specify whether the given non-type template argument
- /// was deduced from an array bound.
- void setDeducedFromArrayBound(bool Deduced) {
- DeducedFromArrayBound = Deduced;
- }
- };
-}
-
-#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 403d5543a64f..5c77ed61060b 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -10,16 +10,21 @@
//
//===----------------------------------------------------------------------===/
-#include "Sema.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
#include <algorithm>
namespace clang {
+ using namespace sema;
+
/// \brief Various flags that control template argument deduction.
///
/// These flags can be bitwise-OR'd together.
@@ -74,7 +79,7 @@ DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgument &Param,
const TemplateArgument &Arg,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced);
/// \brief If the given expression is of a form that permits the deduction
@@ -97,7 +102,7 @@ DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
llvm::APSInt Value, QualType ValueType,
bool DeducedFromArrayBound,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
@@ -138,7 +143,7 @@ static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
Expr *Value,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
@@ -180,7 +185,7 @@ static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
Decl *D,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
@@ -214,7 +219,7 @@ DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
TemplateName Param,
TemplateName Arg,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
if (!ParamDecl) {
@@ -278,7 +283,7 @@ DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateSpecializationType *Param,
QualType Arg,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(Arg.isCanonical() && "Argument type must be canonical");
@@ -345,6 +350,29 @@ DeduceTemplateArguments(Sema &S,
return Sema::TDK_Success;
}
+/// \brief Determines whether the given type is an opaque type that
+/// might be more qualified when instantiated.
+static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
+ switch (T->getTypeClass()) {
+ case Type::TypeOfExpr:
+ case Type::TypeOf:
+ case Type::DependentName:
+ case Type::Decltype:
+ case Type::UnresolvedUsing:
+ return true;
+
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ case Type::VariableArray:
+ case Type::DependentSizedArray:
+ return IsPossiblyOpaquelyQualifiedType(
+ cast<ArrayType>(T)->getElementType());
+
+ default:
+ return false;
+ }
+}
+
/// \brief Deduce the template arguments by comparing the parameter type and
/// the argument type (C++ [temp.deduct.type]).
///
@@ -370,7 +398,7 @@ static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
QualType ParamIn, QualType ArgIn,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
unsigned TDF) {
// We only want to look at the canonical types, since typedefs and
@@ -428,9 +456,9 @@ DeduceTemplateArguments(Sema &S,
// type.
if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = Deduced[Index];
+ Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
- return Sema::TDK_InconsistentQuals;
+ return Sema::TDK_Underqualified;
}
assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
@@ -469,7 +497,7 @@ DeduceTemplateArguments(Sema &S,
if (TDF & TDF_ParamWithReferenceType) {
if (Param.isMoreQualifiedThan(Arg))
return Sema::TDK_NonDeducedMismatch;
- } else {
+ } else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
return Sema::TDK_NonDeducedMismatch;
}
@@ -530,10 +558,11 @@ DeduceTemplateArguments(Sema &S,
if (!IncompleteArrayArg)
return Sema::TDK_NonDeducedMismatch;
+ unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
return DeduceTemplateArguments(S, TemplateParams,
S.Context.getAsIncompleteArrayType(Param)->getElementType(),
IncompleteArrayArg->getElementType(),
- Info, Deduced, 0);
+ Info, Deduced, SubTDF);
}
// T [integer-constant]
@@ -548,10 +577,11 @@ DeduceTemplateArguments(Sema &S,
if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
return Sema::TDK_NonDeducedMismatch;
+ unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
return DeduceTemplateArguments(S, TemplateParams,
ConstantArrayParm->getElementType(),
ConstantArrayArg->getElementType(),
- Info, Deduced, 0);
+ Info, Deduced, SubTDF);
}
// type [i]
@@ -560,6 +590,8 @@ DeduceTemplateArguments(Sema &S,
if (!ArrayArg)
return Sema::TDK_NonDeducedMismatch;
+ unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
+
// Check the element type of the arrays
const DependentSizedArrayType *DependentArrayParm
= S.Context.getAsDependentSizedArrayType(Param);
@@ -567,7 +599,7 @@ DeduceTemplateArguments(Sema &S,
= DeduceTemplateArguments(S, TemplateParams,
DependentArrayParm->getElementType(),
ArrayArg->getElementType(),
- Info, Deduced, 0))
+ Info, Deduced, SubTDF))
return Result;
// Determine the array bound is something we can deduce.
@@ -797,7 +829,7 @@ DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgument &Param,
const TemplateArgument &Arg,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
switch (Param.getKind()) {
case TemplateArgument::Null:
@@ -847,7 +879,6 @@ DeduceTemplateArguments(Sema &S,
return Sema::TDK_NonDeducedMismatch;
}
- assert(false && "Type/value mismatch");
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
@@ -868,7 +899,6 @@ DeduceTemplateArguments(Sema &S,
return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
Info, Deduced);
- assert(false && "Type/value mismatch");
Info.FirstArg = Param;
Info.SecondArg = Arg;
return Sema::TDK_NonDeducedMismatch;
@@ -890,7 +920,7 @@ DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
const TemplateArgumentList &ParamList,
const TemplateArgumentList &ArgList,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
assert(ParamList.size() == ArgList.size());
for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
@@ -974,7 +1004,7 @@ FinishTemplateArgumentDeduction(Sema &S,
ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentList &TemplateArgs,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- Sema::TemplateDeductionInfo &Info) {
+ TemplateDeductionInfo &Info) {
// Trap errors.
Sema::SFINAETrap Trap(S);
@@ -1010,7 +1040,7 @@ FinishTemplateArgumentDeduction(Sema &S,
// to the class template.
// FIXME: Do we have to correct the types of deduced non-type template
// arguments (in particular, integral non-type template arguments?).
- Sema::LocalInstantiationScope InstScope(S);
+ LocalInstantiationScope InstScope(S);
ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
const TemplateArgumentLoc *PartialTemplateArgs
= Partial->getTemplateArgsAsWritten();
@@ -1245,7 +1275,8 @@ Sema::SubstituteExplicitTemplateArguments(
Proto->isVariadic(),
Proto->getTypeQuals(),
Function->getLocation(),
- Function->getDeclName());
+ Function->getDeclName(),
+ Proto->getExtInfo());
if (FunctionType->isNull() || Trap.hasErrorOccurred())
return TDK_SubstitutionFailure;
}
@@ -1486,14 +1517,22 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
return TDK_Success;
}
+/// Gets the type of a function for template-argument-deducton
+/// purposes when it's considered as part of an overload set.
static QualType GetTypeOfFunction(ASTContext &Context,
- bool isAddressOfOperand,
+ const OverloadExpr::FindResult &R,
FunctionDecl *Fn) {
- if (!isAddressOfOperand) return Fn->getType();
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
- if (Method->isInstance())
+ if (Method->isInstance()) {
+ // An instance method that's referenced in a form that doesn't
+ // look like a member pointer is just invalid.
+ if (!R.HasFormOfMemberPointer) return QualType();
+
return Context.getMemberPointerType(Fn->getType(),
Context.getTypeDeclType(Method->getParent()).getTypePtr());
+ }
+
+ if (!R.IsAddressOfOperand) return Fn->getType();
return Context.getPointerType(Fn->getType());
}
@@ -1503,11 +1542,19 @@ static QualType GetTypeOfFunction(ASTContext &Context,
/// undeduced context
static QualType
ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
- Expr *Arg, QualType ParamType) {
- llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
+ Expr *Arg, QualType ParamType,
+ bool ParamWasReference) {
+
+ OverloadExpr::FindResult R = OverloadExpr::find(Arg);
- bool isAddressOfOperand = bool(R.getInt());
- OverloadExpr *Ovl = R.getPointer();
+ OverloadExpr *Ovl = R.Expression;
+
+ // C++0x [temp.deduct.call]p4
+ unsigned TDF = 0;
+ if (ParamWasReference)
+ TDF |= TDF_ParamWithReferenceType;
+ if (R.IsAddressOfOperand)
+ TDF |= TDF_IgnoreQualifiers;
// If there were explicit template arguments, we can only find
// something via C++ [temp.arg.explicit]p3, i.e. if the arguments
@@ -1516,7 +1563,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
// But we can still look for an explicit specialization.
if (FunctionDecl *ExplicitSpec
= S.ResolveSingleFunctionTemplateSpecialization(Ovl))
- return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
+ return GetTypeOfFunction(S.Context, R, ExplicitSpec);
return QualType();
}
@@ -1541,8 +1588,14 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
return QualType();
FunctionDecl *Fn = cast<FunctionDecl>(D);
- QualType ArgType = GetTypeOfFunction(S.Context, isAddressOfOperand, Fn);
+ QualType ArgType = GetTypeOfFunction(S.Context, R, Fn);
+ if (ArgType.isNull()) continue;
+ // Function-to-pointer conversion.
+ if (!ParamWasReference && ParamType->isPointerType() &&
+ ArgType->isFunctionType())
+ ArgType = S.Context.getPointerType(ArgType);
+
// - If the argument is an overload set (not containing function
// templates), trial argument deduction is attempted using each
// of the members of the set. If deduction succeeds for only one
@@ -1557,9 +1610,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
// So we do not reject deductions which were made elsewhere.
llvm::SmallVector<DeducedTemplateArgument, 8>
Deduced(TemplateParams->size());
- Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
- unsigned TDF = 0;
-
+ TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
Sema::TemplateDeductionResult Result
= DeduceTemplateArguments(S, TemplateParams,
ParamType, ArgType,
@@ -1624,7 +1675,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// The types of the parameters from which we will perform template argument
// deduction.
- Sema::LocalInstantiationScope InstScope(*this);
+ LocalInstantiationScope InstScope(*this);
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
@@ -1654,20 +1705,40 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
QualType ParamType = ParamTypes[I];
QualType ArgType = Args[I]->getType();
+ // C++0x [temp.deduct.call]p3:
+ // If P is a cv-qualified type, the top level cv-qualifiers of P’s type
+ // are ignored for type deduction.
+ if (ParamType.getCVRQualifiers())
+ ParamType = ParamType.getLocalUnqualifiedType();
+ const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>();
+ if (ParamRefType) {
+ // [...] If P is a reference type, the type referred to by P is used
+ // for type deduction.
+ ParamType = ParamRefType->getPointeeType();
+ }
+
// Overload sets usually make this parameter an undeduced
// context, but there are sometimes special circumstances.
if (ArgType == Context.OverloadTy) {
ArgType = ResolveOverloadForDeduction(*this, TemplateParams,
- Args[I], ParamType);
+ Args[I], ParamType,
+ ParamRefType != 0);
if (ArgType.isNull())
continue;
}
- // C++ [temp.deduct.call]p2:
- // If P is not a reference type:
- QualType CanonParamType = Context.getCanonicalType(ParamType);
- bool ParamWasReference = isa<ReferenceType>(CanonParamType);
- if (!ParamWasReference) {
+ if (ParamRefType) {
+ // C++0x [temp.deduct.call]p3:
+ // [...] If P is of the form T&&, where T is a template parameter, and
+ // the argument is an lvalue, the type A& is used in place of A for
+ // type deduction.
+ if (ParamRefType->isRValueReferenceType() &&
+ ParamRefType->getAs<TemplateTypeParmType>() &&
+ Args[I]->isLvalue(Context) == Expr::LV_Valid)
+ ArgType = Context.getLValueReferenceType(ArgType);
+ } else {
+ // C++ [temp.deduct.call]p2:
+ // If P is not a reference type:
// - If A is an array type, the pointer type produced by the
// array-to-pointer standard conversion (4.2) is used in place of
// A for type deduction; otherwise,
@@ -1682,30 +1753,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// - If A is a cv-qualified type, the top level cv-qualifiers of A’s
// type are ignored for type deduction.
QualType CanonArgType = Context.getCanonicalType(ArgType);
- if (CanonArgType.getLocalCVRQualifiers())
- ArgType = CanonArgType.getLocalUnqualifiedType();
+ if (ArgType.getCVRQualifiers())
+ ArgType = ArgType.getUnqualifiedType();
}
}
- // C++0x [temp.deduct.call]p3:
- // If P is a cv-qualified type, the top level cv-qualifiers of P’s type
- // are ignored for type deduction.
- if (CanonParamType.getLocalCVRQualifiers())
- ParamType = CanonParamType.getLocalUnqualifiedType();
- if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
- // [...] If P is a reference type, the type referred to by P is used
- // for type deduction.
- ParamType = ParamRefType->getPointeeType();
-
- // [...] If P is of the form T&&, where T is a template parameter, and
- // the argument is an lvalue, the type A& is used in place of A for
- // type deduction.
- if (isa<RValueReferenceType>(ParamRefType) &&
- ParamRefType->getAs<TemplateTypeParmType>() &&
- Args[I]->isLvalue(Context) == Expr::LV_Valid)
- ArgType = Context.getLValueReferenceType(ArgType);
- }
-
// C++0x [temp.deduct.call]p4:
// In general, the deduction process attempts to find template argument
// values that will make the deduced A identical to A (after the type A
@@ -1715,12 +1767,13 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// - If the original P is a reference type, the deduced A (i.e., the
// type referred to by the reference) can be more cv-qualified than
// the transformed A.
- if (ParamWasReference)
+ if (ParamRefType)
TDF |= TDF_ParamWithReferenceType;
// - The transformed A can be another pointer or pointer to member
// type that can be converted to the deduced A via a qualification
// conversion (4.4).
- if (ArgType->isPointerType() || ArgType->isMemberPointerType())
+ if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
+ ArgType->isObjCObjectPointerType())
TDF |= TDF_IgnoreQualifiers;
// - If P is a class and P has the form simple-template-id, then the
// transformed A can be a derived class of the deduced A. Likewise,
@@ -1783,7 +1836,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
QualType FunctionType = Function->getType();
// Substitute any explicit template arguments.
- Sema::LocalInstantiationScope InstScope(*this);
+ LocalInstantiationScope InstScope(*this);
llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
unsigned NumExplicitlySpecified = 0;
llvm::SmallVector<QualType, 4> ParamTypes;
@@ -1915,7 +1968,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// modulo the various allowed differences.
// Finish template argument deduction.
- Sema::LocalInstantiationScope InstScope(*this);
+ LocalInstantiationScope InstScope(*this);
FunctionDecl *Spec = 0;
TemplateDeductionResult Result
= FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec,
@@ -1979,7 +2032,7 @@ static Sema::TemplateDeductionResult
DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
TemplateParameterList *TemplateParams,
QualType ParamIn, QualType ArgIn,
- Sema::TemplateDeductionInfo &Info,
+ TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
CanQualType Param = S.Context.getCanonicalType(ParamIn);
@@ -2061,7 +2114,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
// C++0x [temp.deduct.partial]p3:
// The types used to determine the ordering depend on the context in which
// the partial ordering is done:
- Sema::TemplateDeductionInfo Info(S.Context, Loc);
+ TemplateDeductionInfo Info(S.Context, Loc);
switch (TPOC) {
case TPOC_Call: {
// - In the context of a function call, the function parameter types are
@@ -2386,7 +2439,7 @@ Sema::getMoreSpecializedPartialSpecialization(
// template partial specialization's template arguments, for
// example.
llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
- Sema::TemplateDeductionInfo Info(Context, Loc);
+ TemplateDeductionInfo Info(Context, Loc);
QualType PT1 = PS1->getInjectedSpecializationType();
QualType PT2 = PS2->getInjectedSpecializationType();
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 0cdc8a12ab73..4d4c18130b01 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -10,17 +10,20 @@
//
//===----------------------------------------------------------------------===/
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
#include "TreeTransform.h"
-#include "Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/DeclTemplate.h"
-#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/LangOptions.h"
using namespace clang;
+using namespace sema;
//===----------------------------------------------------------------------===/
// Template Instantiation Support
@@ -614,10 +617,10 @@ namespace {
QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType T);
- Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
- Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
- Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
- Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
+ ExprResult TransformPredefinedExpr(PredefinedExpr *E);
+ ExprResult TransformDeclRefExpr(DeclRefExpr *E);
+ ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+ ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
NonTypeTemplateParmDecl *D);
QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
@@ -631,9 +634,9 @@ namespace {
TemplateTypeParmTypeLoc TL,
QualType ObjectType);
- Sema::OwningExprResult TransformCallExpr(CallExpr *CE) {
+ ExprResult TransformCallExpr(CallExpr *CE) {
getSema().CallsUndergoingInstantiation.push_back(CE);
- OwningExprResult Result =
+ ExprResult Result =
TreeTransform<TemplateInstantiator>::TransformCallExpr(CE);
getSema().CallsUndergoingInstantiation.pop_back();
return move(Result);
@@ -768,7 +771,7 @@ TemplateInstantiator::RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
NNS, T);
}
-Sema::OwningExprResult
+ExprResult
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
return SemaRef.Owned(E->Retain());
@@ -790,7 +793,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
return getSema().Owned(PE);
}
-Sema::OwningExprResult
+ExprResult
TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
NonTypeTemplateParmDecl *NTTP) {
// If the corresponding template argument is NULL or non-existent, it's
@@ -818,7 +821,7 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
getSema().FindInstantiatedDecl(E->getLocation(),
VD, TemplateArgs));
if (!VD)
- return SemaRef.ExprError();
+ return ExprError();
// Derive the type we want the substituted decl to have. This had
// better be non-dependent, or these checks will have serious problems.
@@ -837,7 +840,7 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
}
-Sema::OwningExprResult
+ExprResult
TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
NamedDecl *D = E->getDecl();
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
@@ -851,7 +854,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
}
-Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
+ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
CXXDefaultArgExpr *E) {
assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
getDescribedFunctionTemplate() &&
@@ -865,7 +868,7 @@ QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL,
QualType ObjectType) {
// We need a local instantiation scope for this function prototype.
- Sema::LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+ LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
return inherited::TransformFunctionProtoType(TLB, TL, ObjectType);
}
@@ -1067,7 +1070,8 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
- // Set DeclContext if inside a Block.
+ // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
+ // can be anything, is this right ?
NewParm->setDeclContext(CurContext);
return NewParm;
@@ -1100,11 +1104,11 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
continue;
}
- QualType BaseType = SubstType(Base->getType(),
- TemplateArgs,
- Base->getSourceRange().getBegin(),
- DeclarationName());
- if (BaseType.isNull()) {
+ TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+ TemplateArgs,
+ Base->getSourceRange().getBegin(),
+ DeclarationName());
+ if (!BaseTypeLoc) {
Invalid = true;
continue;
}
@@ -1114,9 +1118,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
Base->getSourceRange(),
Base->isVirtual(),
Base->getAccessSpecifierAsWritten(),
- BaseType,
- /*FIXME: Not totally accurate */
- Base->getSourceRange().getBegin()))
+ BaseTypeLoc))
InstantiatedBases.push_back(InstantiatedBase);
else
Invalid = true;
@@ -1199,13 +1201,16 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// PushDeclContext because we don't have a scope.
ContextRAII SavedContext(*this, Instantiation);
EnterExpressionEvaluationContext EvalContext(*this,
- Action::PotentiallyEvaluated);
+ Sema::PotentiallyEvaluated);
// If this is an instantiation of a local class, merge this local
// instantiation scope with the enclosing scope. Otherwise, every
// instantiation of a class has its own local instantiation scope.
bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
- Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope);
+ LocalInstantiationScope Scope(*this, MergeWithParentScope);
+
+ // Pull attributes from the pattern onto the instantiation.
+ InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
// Start the definition of this instantiation.
Instantiation->startDefinition();
@@ -1216,14 +1221,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
Invalid = true;
- llvm::SmallVector<DeclPtrTy, 4> Fields;
+ llvm::SmallVector<Decl*, 4> Fields;
for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
MemberEnd = Pattern->decls_end();
Member != MemberEnd; ++Member) {
Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs);
if (NewMember) {
if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
- Fields.push_back(DeclPtrTy::make(Field));
+ Fields.push_back(Field);
else if (NewMember->isInvalidDecl())
Invalid = true;
} else {
@@ -1234,7 +1239,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
}
// Finish checking fields.
- ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
+ ActOnFields(0, Instantiation->getLocation(), Instantiation,
Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
0);
CheckCompletedCXXClass(Instantiation);
@@ -1416,12 +1421,6 @@ Sema::InstantiateClassTemplateSpecialization(
TSK,
Complain);
- for (unsigned I = 0, N = Matched.size(); I != N; ++I) {
- // FIXME: Implement TemplateArgumentList::Destroy!
- // if (Matched[I].first != Pattern)
- // Matched[I].second->Destroy(Context);
- }
-
return Result;
}
@@ -1583,7 +1582,7 @@ Sema::InstantiateClassTemplateSpecializationMembers(
TSK);
}
-Sema::OwningStmtResult
+StmtResult
Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
if (!S)
return Owned(S);
@@ -1594,7 +1593,7 @@ Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
return Instantiator.TransformStmt(S);
}
-Sema::OwningExprResult
+ExprResult
Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
if (!E)
return Owned(E);
@@ -1615,6 +1614,15 @@ Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
return Instantiator.TransformNestedNameSpecifier(NNS, Range);
}
+/// \brief Do template substitution on declaration name info.
+DeclarationNameInfo
+Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+ const MultiLevelTemplateArgumentList &TemplateArgs) {
+ TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
+ NameInfo.getName());
+ return Instantiator.TransformDeclarationNameInfo(NameInfo);
+}
+
TemplateName
Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
const MultiLevelTemplateArgumentList &TemplateArgs) {
@@ -1631,7 +1639,7 @@ bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
return Instantiator.TransformTemplateArgument(Input, Output);
}
-Decl *Sema::LocalInstantiationScope::getInstantiationOf(const Decl *D) {
+Decl *LocalInstantiationScope::getInstantiationOf(const Decl *D) {
for (LocalInstantiationScope *Current = this; Current;
Current = Current->Outer) {
// Check if we found something within this scope.
@@ -1650,8 +1658,7 @@ Decl *Sema::LocalInstantiationScope::getInstantiationOf(const Decl *D) {
return 0;
}
-void Sema::LocalInstantiationScope::InstantiatedLocal(const Decl *D,
- Decl *Inst) {
+void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
Decl *&Stored = LocalDecls[D];
assert((!Stored || Stored == Inst)&& "Already instantiated this local");
Stored = Inst;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2fd35285324e..1c7869fecd86 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -9,8 +9,10 @@
// This file implements C++ template instantiation for declarations.
//
//===----------------------------------------------------------------------===/
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Template.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
@@ -19,7 +21,6 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Lex/Preprocessor.h"
using namespace clang;
@@ -31,11 +32,7 @@ namespace {
DeclContext *Owner;
const MultiLevelTemplateArgumentList &TemplateArgs;
- void InstantiateAttrs(Decl *Tmpl, Decl *New);
-
public:
- typedef Sema::OwningExprResult OwningExprResult;
-
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs)
: SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
@@ -87,10 +84,6 @@ namespace {
return 0;
}
- const LangOptions &getLangOptions() {
- return SemaRef.getLangOptions();
- }
-
// Helper functions for instantiating methods.
TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
llvm::SmallVectorImpl<ParmVarDecl *> &Params);
@@ -144,28 +137,38 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
}
// FIXME: Is this still too simple?
-void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
- for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
- TmplAttr = TmplAttr->getNext()) {
+void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+ Decl *Tmpl, Decl *New) {
+ for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+ i != e; ++i) {
+ const Attr *TmplAttr = *i;
// FIXME: This should be generalized to more than just the AlignedAttr.
if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
- if (Aligned->isDependent()) {
+ if (Aligned->isAlignmentDependent()) {
// The alignment expression is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::Unevaluated);
-
- OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(),
- TemplateArgs);
- if (!Result.isInvalid())
- // FIXME: Is this the correct source location?
- SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
- New, Result.takeAs<Expr>());
+ EnterExpressionEvaluationContext Unevaluated(*this,
+ Sema::Unevaluated);
+
+ if (Aligned->isAlignmentExpr()) {
+ ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+ TemplateArgs);
+ if (!Result.isInvalid())
+ AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+ }
+ else {
+ TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+ TemplateArgs,
+ Aligned->getLocation(),
+ DeclarationName());
+ if (Result)
+ AddAlignedAttr(Aligned->getLocation(), New, Result);
+ }
continue;
}
}
// FIXME: Is cloning correct for all attributes?
- Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
+ Attr *NewAttr = TmplAttr->clone(Context);
New->addAttr(NewAttr);
}
}
@@ -234,7 +237,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
}
- InstantiateAttrs(D, Typedef);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
Typedef->setAccess(D->getAccess());
Owner->addDecl(Typedef);
@@ -249,14 +252,14 @@ static bool InstantiateInitializationArguments(Sema &SemaRef,
Expr **Args, unsigned NumArgs,
const MultiLevelTemplateArgumentList &TemplateArgs,
llvm::SmallVectorImpl<SourceLocation> &FakeCommaLocs,
- ASTOwningVector<&ActionBase::DeleteExpr> &InitArgs) {
+ ASTOwningVector<Expr*> &InitArgs) {
for (unsigned I = 0; I != NumArgs; ++I) {
// When we hit the first defaulted argument, break out of the loop:
// we don't pass those default arguments on.
if (Args[I]->isDefaultArgument())
break;
- Sema::OwningExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
+ ExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
if (Arg.isInvalid())
return true;
@@ -288,7 +291,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
const MultiLevelTemplateArgumentList &TemplateArgs,
SourceLocation &LParenLoc,
llvm::SmallVector<SourceLocation, 4> &CommaLocs,
- ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+ ASTOwningVector<Expr*> &NewArgs,
SourceLocation &RParenLoc) {
NewArgs.clear();
LParenLoc = SourceLocation();
@@ -331,7 +334,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
}
}
- Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+ ExprResult Result = S.SubstExpr(Init, TemplateArgs);
if (Result.isInvalid())
return true;
@@ -363,7 +366,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
D->getStorageClassAsWritten());
Var->setThreadSpecified(D->isThreadSpecified());
Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
- Var->setDeclaredInCondition(D->isDeclaredInCondition());
// Substitute the nested name specifier, if any.
if (SubstQualifier(D, Var))
@@ -399,7 +401,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
if (Owner->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
}
- InstantiateAttrs(D, Var);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
// Link instantiations of static data members back to the template from
// which they were instantiated.
@@ -418,25 +420,23 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// Instantiate the initializer.
SourceLocation LParenLoc, RParenLoc;
llvm::SmallVector<SourceLocation, 4> CommaLocs;
- ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+ ASTOwningVector<Expr*> InitArgs(SemaRef);
if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
CommaLocs, InitArgs, RParenLoc)) {
// Attach the initializer to the declaration.
if (D->hasCXXDirectInitializer()) {
// Add the direct initializer to the declaration.
- SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
+ SemaRef.AddCXXDirectInitializerToDecl(Var,
LParenLoc,
move_arg(InitArgs),
CommaLocs.data(),
RParenLoc);
} else if (InitArgs.size() == 1) {
- Expr *Init = (Expr*)(InitArgs.take()[0]);
- SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var),
- SemaRef.Owned(Init),
- false);
+ Expr *Init = InitArgs.take()[0];
+ SemaRef.AddInitializerToDecl(Var, Init, false);
} else {
assert(InitArgs.size() == 0);
- SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+ SemaRef.ActOnUninitializedDecl(Var, false);
}
} else {
// FIXME: Not too happy about invalidating the declaration
@@ -446,12 +446,12 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
SemaRef.PopExpressionEvaluationContext();
} else if (!Var->isStaticDataMember() || Var->isOutOfLine())
- SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+ SemaRef.ActOnUninitializedDecl(Var, false);
// Diagnose unused local variables.
if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed())
SemaRef.DiagnoseUnusedDecl(Var);
-
+
return Var;
}
@@ -493,9 +493,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
BitWidth = 0;
else if (BitWidth) {
// The bit-width expression is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- OwningExprResult InstantiatedBitWidth
+ ExprResult InstantiatedBitWidth
= SemaRef.SubstExpr(BitWidth, TemplateArgs);
if (InstantiatedBitWidth.isInvalid()) {
Invalid = true;
@@ -518,7 +518,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
return 0;
}
- InstantiateAttrs(D, Field);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
if (Invalid)
Field->setInvalidDecl();
@@ -529,7 +529,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
}
if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
if (Parent->isAnonymousStructOrUnion() &&
- Parent->getLookupContext()->isFunctionOrMethod())
+ Parent->getRedeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
}
@@ -581,20 +581,18 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
Expr *AssertExpr = D->getAssertExpr();
// The expression in a static assertion is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- OwningExprResult InstantiatedAssertExpr
+ ExprResult InstantiatedAssertExpr
= SemaRef.SubstExpr(AssertExpr, TemplateArgs);
if (InstantiatedAssertExpr.isInvalid())
return 0;
- OwningExprResult Message(SemaRef, D->getMessage());
+ ExprResult Message(D->getMessage());
D->getMessage()->Retain();
- Decl *StaticAssert
- = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
- move(InstantiatedAssertExpr),
- move(Message)).getAs<Decl>();
- return StaticAssert;
+ return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+ InstantiatedAssertExpr.get(),
+ Message.get());
}
Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
@@ -611,18 +609,18 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
if (D->getDeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
- llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
+ llvm::SmallVector<Decl*, 4> Enumerators;
EnumConstantDecl *LastEnumConst = 0;
for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
ECEnd = D->enumerator_end();
EC != ECEnd; ++EC) {
// The specified value for the enumerator.
- OwningExprResult Value = SemaRef.Owned((Expr *)0);
+ ExprResult Value = SemaRef.Owned((Expr *)0);
if (Expr *UninstValue = EC->getInitExpr()) {
// The enumerator's value expression is not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::Unevaluated);
+ Sema::Unevaluated);
Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
}
@@ -637,7 +635,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
EnumConstantDecl *EnumConst
= SemaRef.CheckEnumConstant(Enum, LastEnumConst,
EC->getLocation(), EC->getIdentifier(),
- move(Value));
+ Value.get());
if (isInvalid) {
if (EnumConst)
@@ -648,7 +646,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
if (EnumConst) {
EnumConst->setAccess(Enum->getAccess());
Enum->addDecl(EnumConst);
- Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
+ Enumerators.push_back(EnumConst);
LastEnumConst = EnumConst;
if (D->getDeclContext()->isFunctionOrMethod()) {
@@ -662,8 +660,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
// FIXME: Fixup LBraceLoc and RBraceLoc
// FIXME: Empty Scope and AttributeList (required to handle attribute packed).
SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(),
- Sema::DeclPtrTy::make(Enum),
- &Enumerators[0], Enumerators.size(),
+ Enum,
+ Enumerators.data(), Enumerators.size(),
0, 0);
return Enum;
@@ -679,7 +677,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// Create a local instantiation scope for this class template, which
// will contain the instantiations of the template parameters.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
TemplateParameterList *TempParams = D->getTemplateParameters();
TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
if (!InstParams)
@@ -857,16 +855,7 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
if (!InstClassTemplate)
return 0;
- Decl *DCanon = D->getCanonicalDecl();
- for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
- P = InstClassTemplate->getPartialSpecializations().begin(),
- PEnd = InstClassTemplate->getPartialSpecializations().end();
- P != PEnd; ++P) {
- if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
- return &*P;
- }
-
- return 0;
+ return InstClassTemplate->findPartialSpecInstantiatedFromMember(D);
}
Decl *
@@ -875,7 +864,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// will contain the instantiations of the template parameters and then get
// merged with the local instantiation scope for the function template
// itself.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
TemplateParameterList *TempParams = D->getTemplateParameters();
TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
@@ -957,7 +946,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Make sure that anonymous structs and unions are recorded.
if (D->isAnonymousStructOrUnion()) {
Record->setAnonymousStructOrUnion(true);
- if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod())
+ if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
}
@@ -977,20 +966,16 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
void *InsertPos = 0;
if (FunctionTemplate && !TemplateParams) {
- llvm::FoldingSetNodeID ID;
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
- FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
- Innermost.second,
- SemaRef.Context);
- FunctionTemplateSpecializationInfo *Info
- = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ FunctionDecl *SpecFunc
+ = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ InsertPos);
// If we already have a function template specialization, return it.
- if (Info)
- return Info->Function;
+ if (SpecFunc)
+ return SpecFunc;
}
bool isFriend;
@@ -1003,7 +988,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
Owner->isFunctionOrMethod() ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
- Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+ LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1181,7 +1166,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
-
+
+ bool queuedInstantiation = false;
+
if (!SemaRef.getLangOptions().CPlusPlus0x &&
D->isThisDeclarationADefinition()) {
// Check for a function body.
@@ -1198,21 +1185,36 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(),
REnd = Function->redecls_end();
R != REnd; ++R) {
- if (*R != Function &&
- ((*R)->getFriendObjectKind() != Decl::FOK_None)) {
+ if (*R == Function)
+ continue;
+ switch (R->getFriendObjectKind()) {
+ case Decl::FOK_None:
+ if (!queuedInstantiation && R->isUsed(false)) {
+ if (MemberSpecializationInfo *MSInfo
+ = Function->getMemberSpecializationInfo()) {
+ if (MSInfo->getPointOfInstantiation().isInvalid()) {
+ SourceLocation Loc = R->getLocation(); // FIXME
+ MSInfo->setPointOfInstantiation(Loc);
+ SemaRef.PendingLocalImplicitInstantiations.push_back(
+ std::make_pair(Function, Loc));
+ queuedInstantiation = true;
+ }
+ }
+ }
+ break;
+ default:
if (const FunctionDecl *RPattern
- = (*R)->getTemplateInstantiationPattern())
+ = R->getTemplateInstantiationPattern())
if (RPattern->hasBody(RPattern)) {
SemaRef.Diag(Function->getLocation(), diag::err_redefinition)
<< Function->getDeclName();
- SemaRef.Diag((*R)->getLocation(), diag::note_previous_definition);
+ SemaRef.Diag(R->getLocation(), diag::note_previous_definition);
Function->setInvalidDecl();
break;
}
}
}
}
-
}
if (Function->isOverloadedOperator() && !DC->isRecord() &&
@@ -1231,20 +1233,16 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
// We are creating a function template specialization from a function
// template. Check whether there is already a function template
// specialization for this particular set of template arguments.
- llvm::FoldingSetNodeID ID;
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
- FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
- Innermost.second,
- SemaRef.Context);
- FunctionTemplateSpecializationInfo *Info
- = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ FunctionDecl *SpecFunc
+ = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ InsertPos);
// If we already have a function template specialization, return it.
- if (Info)
- return Info->Function;
+ if (SpecFunc)
+ return SpecFunc;
}
bool isFriend;
@@ -1256,7 +1254,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
bool MergeWithParentScope = (TemplateParams != 0) ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
- Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+ LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1313,39 +1311,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
CXXMethodDecl *Method = 0;
- DeclarationName Name = D->getDeclName();
+ DeclarationNameInfo NameInfo
+ = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
- QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
- Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
- SemaRef.Context.getCanonicalType(ClassTy));
Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
- Constructor->getLocation(),
- Name, T, TInfo,
+ NameInfo, T, TInfo,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
false);
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
- QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
- Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
- SemaRef.Context.getCanonicalType(ClassTy));
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
- Destructor->getLocation(), Name,
- T, Destructor->isInlineSpecified(),
+ NameInfo, T,
+ Destructor->isInlineSpecified(),
false);
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
- CanQualType ConvTy
- = SemaRef.Context.getCanonicalType(
- T->getAs<FunctionType>()->getResultType());
- Name = SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(
- ConvTy);
Method = CXXConversionDecl::Create(SemaRef.Context, Record,
- Conversion->getLocation(), Name,
- T, TInfo,
+ NameInfo, T, TInfo,
Conversion->isInlineSpecified(),
Conversion->isExplicit());
} else {
- Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
- D->getDeclName(), T, TInfo,
+ Method = CXXMethodDecl::Create(SemaRef.Context, Record,
+ NameInfo, T, TInfo,
D->isStatic(),
D->getStorageClassAsWritten(),
D->isInlineSpecified());
@@ -1409,8 +1395,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
if (InitMethodInstantiation(Method, D))
Method->setInvalidDecl();
- LookupResult Previous(SemaRef, Name, SourceLocation(),
- Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+ LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+ Sema::ForRedeclaration);
if (!FunctionTemplate || TemplateParams || isFriend) {
SemaRef.LookupQualifiedName(Previous, Record);
@@ -1446,7 +1432,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
else
Owner->addDecl(DeclToAdd);
}
-
+
return Method;
}
@@ -1475,8 +1461,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
TemplateTypeParmDecl *Inst =
TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- TTPT->getDepth() - 1, TTPT->getIndex(),
- TTPT->getName(),
+ TTPT->getDepth() - TemplateArgs.getNumLevels(),
+ TTPT->getIndex(),TTPT->getName(),
D->wasDeclaredWithTypename(),
D->isParameterPack());
@@ -1517,8 +1503,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- D->getDepth() - 1, D->getPosition(),
- D->getIdentifier(), T, DI);
+ D->getDepth() - TemplateArgs.getNumLevels(),
+ D->getPosition(), D->getIdentifier(), T,
+ DI);
if (Invalid)
Param->setInvalidDecl();
@@ -1539,7 +1526,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
{
// Perform the actual substitution of template parameters within a new,
// local instantiation scope.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
InstParams = SubstTemplateParams(TempParams);
if (!InstParams)
return NULL;
@@ -1548,8 +1535,9 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
// Build the template template parameter.
TemplateTemplateParmDecl *Param
= TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- D->getDepth() - 1, D->getPosition(),
- D->getIdentifier(), InstParams);
+ D->getDepth() - TemplateArgs.getNumLevels(),
+ D->getPosition(), D->getIdentifier(),
+ InstParams);
Param->setDefaultArgument(D->getDefaultArgument(), false);
// Introduce this template parameter's instantiation into the instantiation
@@ -1575,22 +1563,22 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
// The nested name specifier is non-dependent, so no transformation
- // is required.
+ // is required. The same holds for the name info.
+ DeclarationNameInfo NameInfo = D->getNameInfo();
// We only need to do redeclaration lookups if we're in a class
// scope (in fact, it's not really even possible in non-class
// scopes).
bool CheckRedeclaration = Owner->isRecord();
- LookupResult Prev(SemaRef, D->getDeclName(), D->getLocation(),
- Sema::LookupUsingDeclName, Sema::ForRedeclaration);
+ LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
+ Sema::ForRedeclaration);
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
- D->getLocation(),
D->getNestedNameRange(),
D->getUsingLocation(),
D->getTargetNestedNameDecl(),
- D->getDeclName(),
+ NameInfo,
D->isTypeName());
CXXScopeSpec SS;
@@ -1666,10 +1654,12 @@ Decl * TemplateDeclInstantiator
SS.setRange(D->getTargetNestedNameRange());
SS.setScopeRep(NNS);
+ // Since NameInfo refers to a typename, it cannot be a C++ special name.
+ // Hence, no tranformation is required for it.
+ DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
NamedDecl *UD =
SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
- D->getUsingLoc(), SS, D->getLocation(),
- D->getDeclName(), 0,
+ D->getUsingLoc(), SS, NameInfo, 0,
/*instantiation*/ true,
/*typename*/ true, D->getTypenameLoc());
if (UD)
@@ -1691,10 +1681,12 @@ Decl * TemplateDeclInstantiator
SS.setRange(D->getTargetNestedNameRange());
SS.setScopeRep(NNS);
+ DeclarationNameInfo NameInfo
+ = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
NamedDecl *UD =
SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
- D->getUsingLoc(), SS, D->getLocation(),
- D->getDeclName(), 0,
+ D->getUsingLoc(), SS, NameInfo, 0,
/*instantiation*/ true,
/*typename*/ false, SourceLocation());
if (UD)
@@ -1735,13 +1727,8 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
}
// Clean up if we had an error.
- if (Invalid) {
- for (ParamVector::iterator PI = Params.begin(), PE = Params.end();
- PI != PE; ++PI)
- if (*PI)
- (*PI)->Destroy(SemaRef.Context);
+ if (Invalid)
return NULL;
- }
TemplateParameterList *InstL
= TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -1767,7 +1754,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Create a local instantiation scope for this class template partial
// specialization, which will contain the instantiations of the template
// parameters.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
// Substitute into the template parameters of the class template partial
// specialization.
@@ -1804,15 +1791,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Figure out where to insert this class template partial specialization
// in the member template's set of class template partial specializations.
- llvm::FoldingSetNodeID ID;
- ClassTemplatePartialSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- SemaRef.Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(), InsertPos);
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
@@ -1871,7 +1853,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
InstTemplateArgs,
CanonType,
0,
- ClassTemplate->getPartialSpecializations().size());
+ ClassTemplate->getNextPartialSpecSequenceNumber());
// Substitute the nested name specifier, if any.
if (SubstQualifier(PartialSpec, InstPartialSpec))
return 0;
@@ -1881,8 +1863,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Add this partial specialization to the set of class template partial
// specializations.
- ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
- InsertPos);
+ ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
return false;
}
@@ -2003,7 +1984,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
Proto->getExtInfo()));
}
- InstantiateAttrs(Tmpl, New);
+ SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
return false;
}
@@ -2078,8 +2059,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
Diag(PatternDecl->getLocation(),
diag::note_explicit_instantiation_here);
Function->setInvalidDecl();
+ } else if (Function->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDefinition) {
+ PendingInstantiations.push_back(
+ std::make_pair(Function, PointOfInstantiation));
}
-
+
return;
}
@@ -2099,13 +2084,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
- std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
if (Recursive)
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
EnterExpressionEvaluationContext EvalContext(*this,
- Action::PotentiallyEvaluated);
- ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
+ Sema::PotentiallyEvaluated);
+ ActOnStartOfFunctionDef(0, Function);
// Introduce a new scope where local variable instantiations will be
// recorded, unless we're actually a member function within a local
@@ -2118,10 +2103,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
LocalInstantiationScope Scope(*this, MergeWithParentScope);
// Introduce the instantiated function parameters into the local
- // instantiation scope.
- for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I)
- Scope.InstantiatedLocal(PatternDecl->getParamDecl(I),
- Function->getParamDecl(I));
+ // instantiation scope, and set the parameter names to those used
+ // in the template.
+ for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
+ const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
+ ParmVarDecl *FunctionParam = Function->getParamDecl(I);
+ FunctionParam->setDeclName(PatternParam->getDeclName());
+ Scope.InstantiatedLocal(PatternParam, FunctionParam);
+ }
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -2139,12 +2128,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
}
// Instantiate the function body.
- OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
+ StmtResult Body = SubstStmt(Pattern, TemplateArgs);
if (Body.isInvalid())
Function->setInvalidDecl();
- ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
+ ActOnFinishFunctionBody(Function, Body.get(),
/*IsInstantiation=*/true);
PerformDependentDiagnostics(PatternDecl, TemplateArgs);
@@ -2156,16 +2145,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// This class may have local implicit instantiations that need to be
// instantiation within this scope.
- PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+ PerformPendingInstantiations(/*LocalOnly=*/true);
Scope.Exit();
if (Recursive) {
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
- PerformPendingImplicitInstantiations();
+ PerformPendingInstantiations();
// Restore the set of pending implicit instantiations.
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -2210,8 +2199,12 @@ void Sema::InstantiateStaticDataMemberDefinition(
diag::err_explicit_instantiation_undefined_member)
<< 2 << Var->getDeclName() << Var->getDeclContext();
Diag(Def->getLocation(), diag::note_explicit_instantiation_here);
- }
-
+ } else if (Var->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDefinition) {
+ PendingInstantiations.push_back(
+ std::make_pair(Var, PointOfInstantiation));
+ }
+
return;
}
@@ -2234,9 +2227,9 @@ void Sema::InstantiateStaticDataMemberDefinition(
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
- std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
if (Recursive)
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -2260,10 +2253,10 @@ void Sema::InstantiateStaticDataMemberDefinition(
if (Recursive) {
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
- PerformPendingImplicitInstantiations();
+ PerformPendingInstantiations();
// Restore the set of pending implicit instantiations.
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -2281,8 +2274,13 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
Inits != InitsEnd; ++Inits) {
CXXBaseOrMemberInitializer *Init = *Inits;
+ // Only instantiate written initializers, let Sema re-construct implicit
+ // ones.
+ if (!Init->isWritten())
+ continue;
+
SourceLocation LParenLoc, RParenLoc;
- ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+ ASTOwningVector<Expr*> NewArgs(*this);
llvm::SmallVector<SourceLocation, 4> CommaLocs;
// Instantiate the initializer.
@@ -2341,7 +2339,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
}
// Assign all the initializers to the new constructor.
- ActOnMemInitializers(DeclPtrTy::make(New),
+ ActOnMemInitializers(New,
/*FIXME: ColonLoc */
SourceLocation(),
NewInits.data(), NewInits.size(),
@@ -2588,7 +2586,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
DeclContext *ParentDC = D->getDeclContext();
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
- ParentDC->isFunctionOrMethod()) {
+ (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
// D is a local of some kind. Look into the map of local
// declarations to their instantiations.
return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
@@ -2729,14 +2727,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
/// \brief Performs template instantiation for all implicit template
/// instantiations we have seen until this point.
-void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+void Sema::PerformPendingInstantiations(bool LocalOnly) {
while (!PendingLocalImplicitInstantiations.empty() ||
- (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+ (!LocalOnly && !PendingInstantiations.empty())) {
PendingImplicitInstantiation Inst;
if (PendingLocalImplicitInstantiations.empty()) {
- Inst = PendingImplicitInstantiations.front();
- PendingImplicitInstantiations.pop_front();
+ Inst = PendingInstantiations.front();
+ PendingInstantiations.pop_front();
} else {
Inst = PendingLocalImplicitInstantiations.front();
PendingLocalImplicitInstantiations.pop_front();
@@ -2744,12 +2742,12 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
// Instantiate function definitions
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {
- PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Function),
- Function->getLocation(), *this,
- Context.getSourceManager(),
- "instantiating function definition");
-
- InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
+ PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
+ "instantiating function definition");
+ bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
+ DefinitionRequired);
continue;
}
@@ -2768,20 +2766,24 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
case TSK_Undeclared:
assert(false && "Cannot instantitiate an undeclared specialization.");
case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
case TSK_ExplicitSpecialization:
- continue; // No longer need implicit instantiation.
+ continue; // No longer need to instantiate this type.
+ case TSK_ExplicitInstantiationDefinition:
+ // We only need an instantiation if the pending instantiation *is* the
+ // explicit instantiation.
+ if (Var != Var->getMostRecentDeclaration()) continue;
case TSK_ImplicitInstantiation:
break;
}
- PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
- Var->getLocation(), *this,
- Context.getSourceManager(),
- "instantiating static data member "
- "definition");
+ PrettyDeclStackTraceEntry CrashInfo(*this, Var, Var->getLocation(),
+ "instantiating static data member "
+ "definition");
- InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+ bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
+ DefinitionRequired);
}
}
@@ -2798,3 +2800,4 @@ void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
}
}
}
+
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index a4fc98cd958e..aa30b5c2da30 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -11,7 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Template.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
@@ -20,13 +21,12 @@
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
-#include <iostream>
-
/// \brief Perform adjustment on the parameter type of a function.
///
/// This routine adjusts the given parameter type @p T to the actual
@@ -266,8 +266,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
case DeclSpec::TST_enum:
case DeclSpec::TST_union:
case DeclSpec::TST_struct: {
- TypeDecl *D
- = dyn_cast_or_null<TypeDecl>(static_cast<Decl *>(DS.getTypeRep()));
+ TypeDecl *D = dyn_cast_or_null<TypeDecl>(DS.getRepAsDecl());
if (!D) {
// This can happen in C++ with ambiguous lookups.
Result = Context.IntTy;
@@ -299,9 +298,11 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
DS.getTypeSpecSign() == 0 &&
"Can't handle qualifiers on typedef names yet!");
- Result = TheSema.GetTypeFromParser(DS.getTypeRep());
-
- if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+ Result = TheSema.GetTypeFromParser(DS.getRepAsType());
+ if (Result.isNull())
+ TheDeclarator.setInvalidType(true);
+ else if (DeclSpec::ProtocolQualifierListTy PQ
+ = DS.getProtocolQualifiers()) {
if (const ObjCObjectType *ObjT = Result->getAs<ObjCObjectType>()) {
// Silently drop any existing protocol qualifiers.
// TODO: determine whether that's the right thing to do.
@@ -336,13 +337,13 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
}
case DeclSpec::TST_typeofType:
// FIXME: Preserve type source info.
- Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+ Result = TheSema.GetTypeFromParser(DS.getRepAsType());
assert(!Result.isNull() && "Didn't get a type for typeof?");
// TypeQuals handled by caller.
Result = Context.getTypeOfType(Result);
break;
case DeclSpec::TST_typeofExpr: {
- Expr *E = static_cast<Expr *>(DS.getTypeRep());
+ Expr *E = DS.getRepAsExpr();
assert(E && "Didn't get an expression for typeof?");
// TypeQuals handled by caller.
Result = TheSema.BuildTypeofExprType(E);
@@ -353,7 +354,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
break;
}
case DeclSpec::TST_decltype: {
- Expr *E = static_cast<Expr *>(DS.getTypeRep());
+ Expr *E = DS.getRepAsExpr();
assert(E && "Didn't get an expression for decltype?");
// TypeQuals handled by caller.
Result = TheSema.BuildDecltypeType(E);
@@ -674,10 +675,9 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
!ArraySize->getType()->isIntegerType()) {
Diag(ArraySize->getLocStart(), diag::err_array_size_non_int)
<< ArraySize->getType() << ArraySize->getSourceRange();
- ArraySize->Destroy(Context);
return QualType();
}
- llvm::APSInt ConstVal(32);
+ llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
if (!ArraySize) {
if (ASM == ArrayType::Star)
T = Context.getVariableArrayType(T, 0, ASM, Quals, Brackets);
@@ -707,7 +707,17 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
isSFINAEContext()? diag::err_typecheck_zero_array_size
: diag::ext_typecheck_zero_array_size)
<< ArraySize->getSourceRange();
+ } else if (!T->isDependentType() && !T->isVariablyModifiedType() &&
+ !T->isIncompleteType()) {
+ // Is the array too large?
+ unsigned ActiveSizeBits
+ = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal);
+ if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
+ Diag(ArraySize->getLocStart(), diag::err_array_too_large)
+ << ConstVal.toString(10)
+ << ArraySize->getSourceRange();
}
+
T = Context.getConstantArrayType(T, ConstVal, ASM, Quals);
}
// If this is not C99, extwarn about VLA's and C99 array size modifiers.
@@ -740,11 +750,8 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
/// \brief Build an ext-vector type.
///
/// Run the required checks for the extended vector type.
-QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
+QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc) {
-
- Expr *Arg = (Expr *)ArraySize.get();
-
// unlike gcc's vector_size attribute, we do not allow vectors to be defined
// in conjunction with complex types (pointers, arrays, functions, etc.).
if (!T->isDependentType() &&
@@ -753,11 +760,11 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
return QualType();
}
- if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+ if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) {
llvm::APSInt vecSize(32);
- if (!Arg->isIntegerConstantExpr(vecSize, Context)) {
+ if (!ArraySize->isIntegerConstantExpr(vecSize, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_not_int)
- << "ext_vector_type" << Arg->getSourceRange();
+ << "ext_vector_type" << ArraySize->getSourceRange();
return QualType();
}
@@ -767,7 +774,7 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
if (vectorSize == 0) {
Diag(AttrLoc, diag::err_attribute_zero_size)
- << Arg->getSourceRange();
+ << ArraySize->getSourceRange();
return QualType();
}
@@ -775,8 +782,7 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
return Context.getExtVectorType(T, vectorSize);
}
- return Context.getDependentSizedExtVectorType(T, ArraySize.takeAs<Expr>(),
- AttrLoc);
+ return Context.getDependentSizedExtVectorType(T, ArraySize, AttrLoc);
}
/// \brief Build a function type.
@@ -812,7 +818,8 @@ QualType Sema::BuildFunctionType(QualType T,
QualType *ParamTypes,
unsigned NumParamTypes,
bool Variadic, unsigned Quals,
- SourceLocation Loc, DeclarationName Entity) {
+ SourceLocation Loc, DeclarationName Entity,
+ const FunctionType::ExtInfo &Info) {
if (T->isArrayType() || T->isFunctionType()) {
Diag(Loc, diag::err_func_returning_array_function)
<< T->isFunctionType() << T;
@@ -834,8 +841,7 @@ QualType Sema::BuildFunctionType(QualType T,
return QualType();
return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
- Quals, false, false, 0, 0,
- FunctionType::ExtInfo());
+ Quals, false, false, 0, 0, Info);
}
/// \brief Build a member pointer type \c T Class::*.
@@ -883,6 +889,14 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
return QualType();
}
+ // In the Microsoft ABI, the class is allowed to be an incomplete
+ // type. In such cases, the compiler makes a worst-case assumption.
+ // We make no such assumption right now, so emit an error if the
+ // class isn't a complete type.
+ if (Context.Target.getCXXABI() == CXXABI_Microsoft &&
+ RequireCompleteType(Loc, Class, diag::err_incomplete_type))
+ return QualType();
+
return Context.getMemberPointerType(T, Class.getTypePtr());
}
@@ -912,8 +926,8 @@ QualType Sema::BuildBlockPointerType(QualType T,
return Context.getBlockPointerType(T);
}
-QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
- QualType QT = QualType::getFromOpaquePtr(Ty);
+QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
+ QualType QT = Ty.get();
if (QT.isNull()) {
if (TInfo) *TInfo = 0;
return QualType();
@@ -955,7 +969,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
T = ConvertDeclSpecToType(*this, D, FnAttrsFromDeclSpec);
if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
- TagDecl* Owned = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+ TagDecl* Owned = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
// Owned is embedded if it was defined here, or if it is the
// very first (i.e., canonical) declaration of this tag type.
Owned->setEmbeddedInDeclarator(Owned->isDefinition() ||
@@ -1174,7 +1188,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
// C++ [dcl.fct]p6:
// Types shall not be defined in return or parameter types.
- TagDecl *Tag = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+ TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
if (Tag->isDefinition())
Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
<< Context.getTypeDeclType(Tag);
@@ -1221,8 +1235,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
ArgTys.reserve(FTI.NumArgs);
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- ParmVarDecl *Param =
- cast<ParmVarDecl>(FTI.ArgInfo[i].Param.getAs<Decl>());
+ ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
QualType ArgTy = Param->getType();
assert(!ArgTy.isNull() && "Couldn't parse type?");
@@ -1295,19 +1308,19 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
case DeclaratorChunk::MemberPointer:
// The scope spec must refer to a class, or be dependent.
+ CXXScopeSpec &SS = DeclType.Mem.Scope();
QualType ClsType;
- if (DeclType.Mem.Scope().isInvalid()) {
+ if (SS.isInvalid()) {
// Avoid emitting extra errors if we already errored on the scope.
D.setInvalidType(true);
- } else if (isDependentScopeSpecifier(DeclType.Mem.Scope())
- || dyn_cast_or_null<CXXRecordDecl>(
- computeDeclContext(DeclType.Mem.Scope()))) {
+ } else if (isDependentScopeSpecifier(SS) ||
+ dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS))) {
NestedNameSpecifier *NNS
- = (NestedNameSpecifier *)DeclType.Mem.Scope().getScopeRep();
+ = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
- ClsType = Context.getDependentNameType(ETK_None, NNSPrefix,
+ ClsType = Context.getDependentNameType(ETK_None, NNSPrefix,
NNS->getAsIdentifier());
break;
@@ -1315,11 +1328,15 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
case NestedNameSpecifier::Global:
llvm_unreachable("Nested-name-specifier must name a type");
break;
-
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
ClsType = QualType(NNS->getAsType(), 0);
- if (NNSPrefix)
+ // Note: if NNS is dependent, then its prefix (if any) is already
+ // included in ClsType; this does not hold if the NNS is
+ // nondependent: in this case (if there is indeed a prefix)
+ // ClsType needs to be wrapped into an elaborated type.
+ if (NNSPrefix && !NNS->isDependent())
ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType);
break;
}
@@ -1455,7 +1472,7 @@ namespace {
}
void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
TypeSourceInfo *TInfo = 0;
- Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
// If we got no declarator info from previous Sema routines,
// just fill with the typespec loc.
@@ -1483,9 +1500,9 @@ namespace {
assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
TL.setParensRange(DS.getTypeofParensRange());
- assert(DS.getTypeRep());
+ assert(DS.getRepAsType());
TypeSourceInfo *TInfo = 0;
- Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
TL.setUnderlyingTInfo(TInfo);
}
void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
@@ -1508,7 +1525,7 @@ namespace {
= TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
if (Keyword == ETK_Typename) {
TypeSourceInfo *TInfo = 0;
- Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
if (TInfo) {
TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc()));
return;
@@ -1526,7 +1543,7 @@ namespace {
= TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
if (Keyword == ETK_Typename) {
TypeSourceInfo *TInfo = 0;
- Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
if (TInfo) {
TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc()));
return;
@@ -1546,7 +1563,7 @@ namespace {
= TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
if (Keyword == ETK_Typename) {
TypeSourceInfo *TInfo = 0;
- Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
if (TInfo) {
TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
TInfo->getTypeLoc()));
@@ -1620,7 +1637,7 @@ namespace {
const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
- ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+ ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
TL.setArg(tpi++, Param);
}
// FIXME: exception specs
@@ -1651,24 +1668,21 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
}
- TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
-
- // We have source information for the return type that was not in the
- // declaration specifiers; copy that information into the current type
- // location so that it will be retained. This occurs, for example, with
- // a C++ conversion function, where the return type occurs within the
- // declarator-id rather than in the declaration specifiers.
- if (ReturnTypeInfo && D.getDeclSpec().getTypeSpecType() == TST_unspecified) {
+ // If we have different source information for the return type, use
+ // that. This really only applies to C++ conversion functions.
+ if (ReturnTypeInfo) {
TypeLoc TL = ReturnTypeInfo->getTypeLoc();
assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+ } else {
+ TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
}
return TInfo;
}
/// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
-QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
+ParsedType Sema::CreateParsedType(QualType T, TypeSourceInfo *TInfo) {
// FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser
// and Sema during declaration parsing. Try deallocating/caching them when
// it's appropriate, instead of allocating them and keeping them around.
@@ -1676,7 +1690,7 @@ QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
new (LocT) LocInfoType(T, TInfo);
assert(LocT->getTypeClass() != T->getTypeClass() &&
"LocInfoType's TypeClass conflicts with an existing Type class");
- return QualType(LocT, 0);
+ return ParsedType::make(QualType(LocT, 0));
}
void LocInfoType::getAsStringInternal(std::string &Str,
@@ -1686,7 +1700,7 @@ void LocInfoType::getAsStringInternal(std::string &Str,
" GetTypeFromParser");
}
-Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
+TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
// C99 6.7.6: Type names have no identifier. This is already validated by
// the parser.
assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
@@ -1710,8 +1724,7 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
<< Context.getTypeDeclType(OwnedTag);
}
- T = CreateLocInfoType(T, TInfo);
- return T.getAsOpaquePtr();
+ return CreateParsedType(T, TInfo);
}
@@ -1825,9 +1838,10 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
// Delay if this is not a function or pointer to block.
if (!Type->isFunctionPointerType()
&& !Type->isBlockPointerType()
- && !Type->isFunctionType())
+ && !Type->isFunctionType()
+ && !Type->isMemberFunctionPointerType())
return true;
-
+
// Otherwise we can process right away.
Type = S.Context.getNoReturnType(Type);
return false;
@@ -1842,7 +1856,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
// Delay if this is not a function or pointer to block.
if (!Type->isFunctionPointerType()
&& !Type->isBlockPointerType()
- && !Type->isFunctionType())
+ && !Type->isFunctionType()
+ && !Type->isMemberFunctionPointerType())
return true;
// Otherwise we can process right away.
@@ -1868,6 +1883,12 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
QualType T = Type;
if (const PointerType *PT = Type->getAs<PointerType>())
T = PT->getPointeeType();
+ else if (const BlockPointerType *BPT = Type->getAs<BlockPointerType>())
+ T = BPT->getPointeeType();
+ else if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>())
+ T = MPT->getPointeeType();
+ else if (const ReferenceType *RT = Type->getAs<ReferenceType>())
+ T = RT->getPointeeType();
const FunctionType *Fn = T->getAs<FunctionType>();
// Delay if the type didn't work out to a function.
@@ -1880,6 +1901,7 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
+ case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
default: llvm_unreachable("unexpected attribute kind"); return false;
}
@@ -1946,8 +1968,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
return;
}
// the base type must be integer or float, and can't already be a vector.
- if (CurType->isVectorType() ||
- (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+ if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
Attr.setInvalid();
return;
@@ -2008,6 +2029,7 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
case AttributeList::AT_fastcall:
case AttributeList::AT_stdcall:
case AttributeList::AT_thiscall:
+ case AttributeList::AT_pascal:
case AttributeList::AT_regparm:
// Don't process these on the DeclSpec.
if (IsDeclSpec ||
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 87e7b9d00b09..1854e7430853 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -12,9 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
#include "TargetAttributesSema.h"
+#include "clang/Sema/SemaInternal.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/Triple.h"
using namespace clang;
@@ -51,8 +52,8 @@ static void HandleMSP430InterruptAttr(Decl *d,
return;
}
- d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
namespace {
@@ -97,7 +98,7 @@ static void HandleX86ForceAlignArgPointerAttr(Decl *D,
return;
}
- D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+ D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +110,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -146,7 +147,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +159,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -177,7 +178,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
}
namespace {
diff --git a/lib/Sema/TargetAttributesSema.h b/lib/Sema/TargetAttributesSema.h
index 8794e4013ec7..410c900222f6 100644
--- a/lib/Sema/TargetAttributesSema.h
+++ b/lib/Sema/TargetAttributesSema.h
@@ -13,7 +13,7 @@
namespace clang {
class Scope;
class Decl;
- class Attr;
+ class AttributeList;
class Sema;
class TargetAttributesSema {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 17103c515f8b..e7bfbe6fe955 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -13,10 +13,12 @@
#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
#define LLVM_CLANG_SEMA_TREETRANSFORM_H
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/ScopeInfo.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
@@ -24,13 +26,14 @@
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TypeLocBuilder.h"
-#include "clang/Parse/Ownership.h"
-#include "clang/Parse/Designator.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/Designator.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
namespace clang {
+using namespace sema;
/// \brief A semantic tree transformation that allows one to transform one
/// abstract syntax tree into another.
@@ -89,14 +92,6 @@ protected:
Sema &SemaRef;
public:
- typedef Sema::OwningStmtResult OwningStmtResult;
- typedef Sema::OwningExprResult OwningExprResult;
- typedef Sema::StmtArg StmtArg;
- typedef Sema::ExprArg ExprArg;
- typedef Sema::MultiExprArg MultiExprArg;
- typedef Sema::MultiStmtArg MultiStmtArg;
- typedef Sema::DeclPtrTy DeclPtrTy;
-
/// \brief Initializes a new tree transformer.
TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
@@ -108,6 +103,9 @@ public:
return static_cast<const Derived&>(*this);
}
+ static inline ExprResult Owned(Expr *E) { return E; }
+ static inline StmtResult Owned(Stmt *S) { return S; }
+
/// \brief Retrieves a reference to the semantic analysis object used for
/// this tree transform.
Sema &getSema() const { return SemaRef; }
@@ -220,7 +218,7 @@ public:
/// other mechanism.
///
/// \returns the transformed statement.
- OwningStmtResult TransformStmt(Stmt *S);
+ StmtResult TransformStmt(Stmt *S);
/// \brief Transform the given expression.
///
@@ -230,7 +228,7 @@ public:
/// other mechanism.
///
/// \returns the transformed expression.
- OwningExprResult TransformExpr(Expr *E);
+ ExprResult TransformExpr(Expr *E);
/// \brief Transform the given declaration, which is referenced from a type
/// or expression.
@@ -276,9 +274,9 @@ public:
/// and destructor names and then (if needed) rebuilds the declaration name.
/// Identifiers and selectors are returned unmodified. Sublcasses may
/// override this function to provide alternate behavior.
- DeclarationName TransformDeclarationName(DeclarationName Name,
- SourceLocation Loc,
- QualType ObjectType = QualType());
+ DeclarationNameInfo
+ TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+ QualType ObjectType = QualType());
/// \brief Transform the given template name.
///
@@ -337,13 +335,13 @@ public:
TransformTemplateSpecializationType(const TemplateSpecializationType *T,
QualType ObjectType);
- OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
- OwningExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
+ StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
+ ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
#define STMT(Node, Parent) \
- OwningStmtResult Transform##Node(Node *S);
+ StmtResult Transform##Node(Node *S);
#define EXPR(Node, Parent) \
- OwningExprResult Transform##Node(Node *E);
+ ExprResult Transform##Node(Node *E);
#define ABSTRACT_STMT(Stmt)
#include "clang/AST/StmtNodes.inc"
@@ -421,7 +419,7 @@ public:
/// Subclasses may override this routine to provide different behavior.
QualType RebuildVariableArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange);
@@ -432,7 +430,7 @@ public:
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDependentSizedArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange);
@@ -458,7 +456,7 @@ public:
/// By default, performs semantic analysis when building the vector type.
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDependentSizedExtVectorType(QualType ElementType,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
SourceLocation AttributeLoc);
/// \brief Build a new function type.
@@ -468,7 +466,8 @@ public:
QualType RebuildFunctionProtoType(QualType T,
QualType *ParamTypes,
unsigned NumParamTypes,
- bool Variadic, unsigned Quals);
+ bool Variadic, unsigned Quals,
+ const FunctionType::ExtInfo &Info);
/// \brief Build a new unprototyped function type.
QualType RebuildFunctionNoProtoType(QualType ResultType);
@@ -496,7 +495,7 @@ public:
///
/// By default, performs semantic analysis when building the typeof type.
/// Subclasses may override this routine to provide different behavior.
- QualType RebuildTypeOfExprType(ExprArg Underlying);
+ QualType RebuildTypeOfExprType(Expr *Underlying);
/// \brief Build a new typeof(type) type.
///
@@ -507,7 +506,7 @@ public:
///
/// By default, performs semantic analysis when building the decltype type.
/// Subclasses may override this routine to provide different behavior.
- QualType RebuildDecltypeType(ExprArg Underlying);
+ QualType RebuildDecltypeType(Expr *Underlying);
/// \brief Build a new template specialization type.
///
@@ -558,7 +557,8 @@ public:
getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
if (T.isNull()) return QualType();
- return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
+ // NOTE: NNS is already recorded in template specialization type T.
+ return SemaRef.Context.getElaboratedType(Keyword, /*NNS=*/0, T);
}
/// \brief Build a new typename type that refers to an identifier.
@@ -707,11 +707,11 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
+ StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
MultiStmtArg Statements,
SourceLocation RBraceLoc,
bool IsStmtExpr) {
- return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
+ return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
IsStmtExpr);
}
@@ -719,12 +719,12 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
- ExprArg LHS,
+ StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
+ Expr *LHS,
SourceLocation EllipsisLoc,
- ExprArg RHS,
+ Expr *RHS,
SourceLocation ColonLoc) {
- return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
+ return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
ColonLoc);
}
@@ -732,19 +732,19 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
- getSema().ActOnCaseStmtBody(S.get(), move(Body));
- return move(S);
+ StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
+ getSema().ActOnCaseStmtBody(S, Body);
+ return S;
}
/// \brief Build a new default statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
+ StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
SourceLocation ColonLoc,
- StmtArg SubStmt) {
- return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
+ Stmt *SubStmt) {
+ return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
/*CurScope=*/0);
}
@@ -752,89 +752,85 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
+ StmtResult RebuildLabelStmt(SourceLocation IdentLoc,
IdentifierInfo *Id,
SourceLocation ColonLoc,
- StmtArg SubStmt) {
- return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
+ Stmt *SubStmt) {
+ return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, SubStmt);
}
/// \brief Build a new "if" statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
- VarDecl *CondVar, StmtArg Then,
- SourceLocation ElseLoc, StmtArg Else) {
- return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar),
- move(Then), ElseLoc, move(Else));
+ StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
+ VarDecl *CondVar, Stmt *Then,
+ SourceLocation ElseLoc, Stmt *Else) {
+ return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
}
/// \brief Start building a new switch statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
- Sema::ExprArg Cond,
- VarDecl *CondVar) {
- return getSema().ActOnStartOfSwitchStmt(SwitchLoc, move(Cond),
- DeclPtrTy::make(CondVar));
+ StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
+ Expr *Cond, VarDecl *CondVar) {
+ return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,
+ CondVar);
}
/// \brief Attach the body to the switch statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
- StmtArg Switch, StmtArg Body) {
- return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
- move(Body));
+ StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
+ Stmt *Switch, Stmt *Body) {
+ return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
}
/// \brief Build a new while statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
+ StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
Sema::FullExprArg Cond,
VarDecl *CondVar,
- StmtArg Body) {
- return getSema().ActOnWhileStmt(WhileLoc, Cond,
- DeclPtrTy::make(CondVar), move(Body));
+ Stmt *Body) {
+ return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);
}
/// \brief Build a new do-while statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
+ StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
SourceLocation WhileLoc,
SourceLocation LParenLoc,
- ExprArg Cond,
+ Expr *Cond,
SourceLocation RParenLoc) {
- return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
- move(Cond), RParenLoc);
+ return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
+ Cond, RParenLoc);
}
/// \brief Build a new for statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
+ StmtResult RebuildForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
- StmtArg Init, Sema::FullExprArg Cond,
+ Stmt *Init, Sema::FullExprArg Cond,
VarDecl *CondVar, Sema::FullExprArg Inc,
- SourceLocation RParenLoc, StmtArg Body) {
- return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond,
- DeclPtrTy::make(CondVar),
- Inc, RParenLoc, move(Body));
+ SourceLocation RParenLoc, Stmt *Body) {
+ return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
+ CondVar,
+ Inc, RParenLoc, Body);
}
/// \brief Build a new goto statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
+ StmtResult RebuildGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
LabelStmt *Label) {
return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
@@ -844,27 +840,27 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
+ StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
SourceLocation StarLoc,
- ExprArg Target) {
- return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
+ Expr *Target) {
+ return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
}
/// \brief Build a new return statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
- ExprArg Result) {
+ StmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
+ Expr *Result) {
- return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
+ return getSema().ActOnReturnStmt(ReturnLoc, Result);
}
/// \brief Build a new declaration statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
+ StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
SourceLocation StartLoc,
SourceLocation EndLoc) {
return getSema().Owned(
@@ -878,7 +874,7 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildAsmStmt(SourceLocation AsmLoc,
+ StmtResult RebuildAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
bool IsVolatile,
unsigned NumOutputs,
@@ -886,13 +882,13 @@ public:
IdentifierInfo **Names,
MultiExprArg Constraints,
MultiExprArg Exprs,
- ExprArg AsmString,
+ Expr *AsmString,
MultiExprArg Clobbers,
SourceLocation RParenLoc,
bool MSAsm) {
return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
NumInputs, Names, move(Constraints),
- move(Exprs), move(AsmString), move(Clobbers),
+ Exprs, AsmString, Clobbers,
RParenLoc, MSAsm);
}
@@ -900,12 +896,12 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
- StmtArg TryBody,
+ StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
+ Stmt *TryBody,
MultiStmtArg CatchStmts,
- StmtArg Finally) {
- return getSema().ActOnObjCAtTryStmt(AtLoc, move(TryBody), move(CatchStmts),
- move(Finally));
+ Stmt *Finally) {
+ return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, move(CatchStmts),
+ Finally);
}
/// \brief Rebuild an Objective-C exception declaration.
@@ -923,59 +919,58 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
+ StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParenLoc,
VarDecl *Var,
- StmtArg Body) {
+ Stmt *Body) {
return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
- Sema::DeclPtrTy::make(Var),
- move(Body));
+ Var, Body);
}
/// \brief Build a new Objective-C @finally statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
- StmtArg Body) {
- return getSema().ActOnObjCAtFinallyStmt(AtLoc, move(Body));
+ StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
+ Stmt *Body) {
+ return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
}
/// \brief Build a new Objective-C @throw statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
- ExprArg Operand) {
- return getSema().BuildObjCAtThrowStmt(AtLoc, move(Operand));
+ StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
+ Expr *Operand) {
+ return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
}
/// \brief Build a new Objective-C @synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
- ExprArg Object,
- StmtArg Body) {
- return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, move(Object),
- move(Body));
+ StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
+ Expr *Object,
+ Stmt *Body) {
+ return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object,
+ Body);
}
/// \brief Build a new Objective-C fast enumeration statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
- SourceLocation LParenLoc,
- StmtArg Element,
- ExprArg Collection,
- SourceLocation RParenLoc,
- StmtArg Body) {
+ StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
+ SourceLocation LParenLoc,
+ Stmt *Element,
+ Expr *Collection,
+ SourceLocation RParenLoc,
+ Stmt *Body) {
return getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
- move(Element),
- move(Collection),
+ Element,
+ Collection,
RParenLoc,
- move(Body));
+ Body);
}
/// \brief Build a new C++ exception declaration.
@@ -995,31 +990,30 @@ public:
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
- VarDecl *ExceptionDecl,
- StmtArg Handler) {
- return getSema().Owned(
- new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
- Handler.takeAs<Stmt>()));
+ StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
+ VarDecl *ExceptionDecl,
+ Stmt *Handler) {
+ return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
+ Handler));
}
/// \brief Build a new C++ try statement.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
- StmtArg TryBlock,
- MultiStmtArg Handlers) {
- return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
+ StmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
+ Stmt *TryBlock,
+ MultiStmtArg Handlers) {
+ return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, move(Handlers));
}
/// \brief Build a new expression that references a declaration.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
- LookupResult &R,
- bool RequiresADL) {
+ ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
+ LookupResult &R,
+ bool RequiresADL) {
return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
}
@@ -1028,33 +1022,34 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- ValueDecl *VD, SourceLocation Loc,
- TemplateArgumentListInfo *TemplateArgs) {
+ ExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ ValueDecl *VD,
+ const DeclarationNameInfo &NameInfo,
+ TemplateArgumentListInfo *TemplateArgs) {
CXXScopeSpec SS;
SS.setScopeRep(Qualifier);
SS.setRange(QualifierRange);
// FIXME: loses template args.
-
- return getSema().BuildDeclarationNameExpr(SS, Loc, VD);
+
+ return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD);
}
/// \brief Build a new expression in parentheses.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
+ ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
SourceLocation RParen) {
- return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
+ return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
}
/// \brief Build a new pseudo-destructor expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
+ ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
SourceLocation OperatorLoc,
bool isArrow,
NestedNameSpecifier *Qualifier,
@@ -1068,19 +1063,19 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
- UnaryOperator::Opcode Opc,
- ExprArg SubExpr) {
- return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
+ ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
+ UnaryOperatorKind Opc,
+ Expr *SubExpr) {
+ return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr);
}
/// \brief Build a new builtin offsetof expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
+ ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
TypeSourceInfo *Type,
- Action::OffsetOfComponent *Components,
+ Sema::OffsetOfComponent *Components,
unsigned NumComponents,
SourceLocation RParenLoc) {
return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
@@ -1091,7 +1086,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
+ ExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
return getSema().CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeOf, R);
@@ -1102,15 +1097,13 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
+ ExprResult RebuildSizeOfAlignOf(Expr *SubExpr, SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
- OwningExprResult Result
- = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
- OpLoc, isSizeOf, R);
+ ExprResult Result
+ = getSema().CreateSizeOfAlignOfExpr(SubExpr, OpLoc, isSizeOf, R);
if (Result.isInvalid())
- return getSema().ExprError();
+ return ExprError();
- SubExpr.release();
return move(Result);
}
@@ -1118,12 +1111,12 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
+ ExprResult RebuildArraySubscriptExpr(Expr *LHS,
SourceLocation LBracketLoc,
- ExprArg RHS,
+ Expr *RHS,
SourceLocation RBracketLoc) {
- return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
- LBracketLoc, move(RHS),
+ return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS,
+ LBracketLoc, RHS,
RBracketLoc);
}
@@ -1131,11 +1124,11 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
+ ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
MultiExprArg Args,
SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
- return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
+ return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
move(Args), CommaLocs, RParenLoc);
}
@@ -1143,11 +1136,11 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
+ ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
bool isArrow,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- SourceLocation MemberLoc,
+ const DeclarationNameInfo &MemberNameInfo,
ValueDecl *Member,
NamedDecl *FoundDecl,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
@@ -1156,14 +1149,13 @@ public:
// We have a reference to an unnamed field.
assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
- Expr *BaseExpr = Base.takeAs<Expr>();
- if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier,
+ if (getSema().PerformObjectMemberConversion(Base, Qualifier,
FoundDecl, Member))
- return getSema().ExprError();
+ return ExprError();
MemberExpr *ME =
- new (getSema().Context) MemberExpr(BaseExpr, isArrow,
- Member, MemberLoc,
+ new (getSema().Context) MemberExpr(Base, isArrow,
+ Member, MemberNameInfo,
cast<FieldDecl>(Member)->getType());
return getSema().Owned(ME);
}
@@ -1174,19 +1166,16 @@ public:
SS.setScopeRep(Qualifier);
}
- Expr *BaseExpr = Base.takeAs<Expr>();
- getSema().DefaultFunctionArrayConversion(BaseExpr);
- QualType BaseType = BaseExpr->getType();
+ getSema().DefaultFunctionArrayConversion(Base);
+ QualType BaseType = Base->getType();
// FIXME: this involves duplicating earlier analysis in a lot of
// cases; we should avoid this when possible.
- LookupResult R(getSema(), Member->getDeclName(), MemberLoc,
- Sema::LookupMemberName);
+ LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
R.addDecl(FoundDecl);
R.resolveKind();
- return getSema().BuildMemberReferenceExpr(getSema().Owned(BaseExpr),
- BaseType, OpLoc, isArrow,
+ return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
SS, FirstQualifierInScope,
R, ExplicitTemplateArgs);
}
@@ -1195,66 +1184,64 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
- BinaryOperator::Opcode Opc,
- ExprArg LHS, ExprArg RHS) {
- return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
- LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
+ ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
+ BinaryOperatorKind Opc,
+ Expr *LHS, Expr *RHS) {
+ return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS);
}
/// \brief Build a new conditional operator expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildConditionalOperator(ExprArg Cond,
+ ExprResult RebuildConditionalOperator(Expr *Cond,
SourceLocation QuestionLoc,
- ExprArg LHS,
+ Expr *LHS,
SourceLocation ColonLoc,
- ExprArg RHS) {
- return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
- move(LHS), move(RHS));
+ Expr *RHS) {
+ return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
+ LHS, RHS);
}
/// \brief Build a new C-style cast expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
+ ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
TypeSourceInfo *TInfo,
SourceLocation RParenLoc,
- ExprArg SubExpr) {
+ Expr *SubExpr) {
return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
- move(SubExpr));
+ SubExpr);
}
/// \brief Build a new compound literal expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
+ ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
TypeSourceInfo *TInfo,
SourceLocation RParenLoc,
- ExprArg Init) {
+ Expr *Init) {
return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
- move(Init));
+ Init);
}
/// \brief Build a new extended vector element access expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
+ ExprResult RebuildExtVectorElementExpr(Expr *Base,
SourceLocation OpLoc,
SourceLocation AccessorLoc,
IdentifierInfo &Accessor) {
CXXScopeSpec SS;
- QualType BaseType = ((Expr*) Base.get())->getType();
- return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+ DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
+ return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
OpLoc, /*IsArrow*/ false,
SS, /*FirstQualifierInScope*/ 0,
- DeclarationName(&Accessor),
- AccessorLoc,
+ NameInfo,
/* TemplateArgs */ 0);
}
@@ -1262,11 +1249,11 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
+ ExprResult RebuildInitList(SourceLocation LBraceLoc,
MultiExprArg Inits,
SourceLocation RBraceLoc,
QualType ResultTy) {
- OwningExprResult Result
+ ExprResult Result
= SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
if (Result.isInvalid() || ResultTy->isDependentType())
return move(Result);
@@ -1282,16 +1269,16 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
+ ExprResult RebuildDesignatedInitExpr(Designation &Desig,
MultiExprArg ArrayExprs,
SourceLocation EqualOrColonLoc,
bool GNUSyntax,
- ExprArg Init) {
- OwningExprResult Result
+ Expr *Init) {
+ ExprResult Result
= SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
- move(Init));
+ Init);
if (Result.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArrayExprs.release();
return move(Result);
@@ -1302,7 +1289,7 @@ public:
/// By default, builds the implicit value initialization without performing
/// any semantic analysis. Subclasses may override this routine to provide
/// different behavior.
- OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
+ ExprResult RebuildImplicitValueInitExpr(QualType T) {
return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
}
@@ -1310,17 +1297,19 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
- QualType T, SourceLocation RParenLoc) {
- return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
- RParenLoc);
+ ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
+ Expr *SubExpr, TypeSourceInfo *TInfo,
+ SourceLocation RParenLoc) {
+ return getSema().BuildVAArgExpr(BuiltinLoc,
+ SubExpr, TInfo,
+ RParenLoc);
}
/// \brief Build a new expression list in parentheses.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
+ ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
MultiExprArg SubExprs,
SourceLocation RParenLoc) {
return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc,
@@ -1332,7 +1321,7 @@ public:
/// By default, performs semantic analysis, using the name of the label
/// rather than attempting to map the label statement itself.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
+ ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
SourceLocation LabelLoc,
LabelStmt *Label) {
return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
@@ -1342,22 +1331,22 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
- StmtArg SubStmt,
+ ExprResult RebuildStmtExpr(SourceLocation LParenLoc,
+ Stmt *SubStmt,
SourceLocation RParenLoc) {
- return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
+ return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc);
}
/// \brief Build a new __builtin_types_compatible_p expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
- QualType T1, QualType T2,
+ ExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ TypeSourceInfo *TInfo1,
+ TypeSourceInfo *TInfo2,
SourceLocation RParenLoc) {
- return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
- T1.getAsOpaquePtr(),
- T2.getAsOpaquePtr(),
+ return getSema().BuildTypesCompatibleExpr(BuiltinLoc,
+ TInfo1, TInfo2,
RParenLoc);
}
@@ -1365,11 +1354,11 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
- ExprArg Cond, ExprArg LHS, ExprArg RHS,
+ ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
+ Expr *Cond, Expr *LHS, Expr *RHS,
SourceLocation RParenLoc) {
return SemaRef.ActOnChooseExpr(BuiltinLoc,
- move(Cond), move(LHS), move(RHS),
+ Cond, LHS, RHS,
RParenLoc);
}
@@ -1381,11 +1370,11 @@ public:
/// operator call into a use of a builtin operator, performing
/// argument-dependent lookup, etc. Subclasses may override this routine to
/// provide different behavior.
- OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+ ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
SourceLocation OpLoc,
- ExprArg Callee,
- ExprArg First,
- ExprArg Second);
+ Expr *Callee,
+ Expr *First,
+ Expr *Second);
/// \brief Build a new C++ "named" cast expression, such as static_cast or
/// reinterpret_cast.
@@ -1393,57 +1382,57 @@ public:
/// By default, this routine dispatches to one of the more-specific routines
/// for a particular named case, e.g., RebuildCXXStaticCastExpr().
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
+ ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
Stmt::StmtClass Class,
SourceLocation LAngleLoc,
TypeSourceInfo *TInfo,
SourceLocation RAngleLoc,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *SubExpr,
SourceLocation RParenLoc) {
switch (Class) {
case Stmt::CXXStaticCastExprClass:
return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
RAngleLoc, LParenLoc,
- move(SubExpr), RParenLoc);
+ SubExpr, RParenLoc);
case Stmt::CXXDynamicCastExprClass:
return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
RAngleLoc, LParenLoc,
- move(SubExpr), RParenLoc);
+ SubExpr, RParenLoc);
case Stmt::CXXReinterpretCastExprClass:
return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
RAngleLoc, LParenLoc,
- move(SubExpr),
+ SubExpr,
RParenLoc);
case Stmt::CXXConstCastExprClass:
return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
RAngleLoc, LParenLoc,
- move(SubExpr), RParenLoc);
+ SubExpr, RParenLoc);
default:
assert(false && "Invalid C++ named cast");
break;
}
- return getSema().ExprError();
+ return ExprError();
}
/// \brief Build a new C++ static_cast expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
+ ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
SourceLocation LAngleLoc,
TypeSourceInfo *TInfo,
SourceLocation RAngleLoc,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *SubExpr,
SourceLocation RParenLoc) {
return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
- TInfo, move(SubExpr),
+ TInfo, SubExpr,
SourceRange(LAngleLoc, RAngleLoc),
SourceRange(LParenLoc, RParenLoc));
}
@@ -1452,15 +1441,15 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
+ ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
SourceLocation LAngleLoc,
TypeSourceInfo *TInfo,
SourceLocation RAngleLoc,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *SubExpr,
SourceLocation RParenLoc) {
return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
- TInfo, move(SubExpr),
+ TInfo, SubExpr,
SourceRange(LAngleLoc, RAngleLoc),
SourceRange(LParenLoc, RParenLoc));
}
@@ -1469,15 +1458,15 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
+ ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
SourceLocation LAngleLoc,
TypeSourceInfo *TInfo,
SourceLocation RAngleLoc,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *SubExpr,
SourceLocation RParenLoc) {
return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
- TInfo, move(SubExpr),
+ TInfo, SubExpr,
SourceRange(LAngleLoc, RAngleLoc),
SourceRange(LParenLoc, RParenLoc));
}
@@ -1486,15 +1475,15 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
+ ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
SourceLocation LAngleLoc,
TypeSourceInfo *TInfo,
SourceLocation RAngleLoc,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *SubExpr,
SourceLocation RParenLoc) {
return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
- TInfo, move(SubExpr),
+ TInfo, SubExpr,
SourceRange(LAngleLoc, RAngleLoc),
SourceRange(LParenLoc, RParenLoc));
}
@@ -1503,16 +1492,15 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
+ ExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
TypeSourceInfo *TInfo,
SourceLocation LParenLoc,
- ExprArg SubExpr,
+ Expr *Sub,
SourceLocation RParenLoc) {
- void *Sub = SubExpr.takeAs<Expr>();
return getSema().ActOnCXXTypeConstructExpr(TypeRange,
- TInfo->getType().getAsOpaquePtr(),
+ ParsedType::make(TInfo->getType()),
LParenLoc,
- Sema::MultiExprArg(getSema(), &Sub, 1),
+ MultiExprArg(&Sub, 1),
/*CommaLocs=*/0,
RParenLoc);
}
@@ -1521,7 +1509,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+ ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
SourceLocation TypeidLoc,
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
@@ -1533,11 +1521,11 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+ ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
SourceLocation TypeidLoc,
- ExprArg Operand,
+ Expr *Operand,
SourceLocation RParenLoc) {
- return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, move(Operand),
+ return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
RParenLoc);
}
@@ -1546,7 +1534,7 @@ public:
/// By default, builds a new "this" expression without performing any
/// semantic analysis. Subclasses may override this routine to provide
/// different behavior.
- OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
+ ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
QualType ThisType,
bool isImplicit) {
return getSema().Owned(
@@ -1558,8 +1546,8 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
- return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
+ ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub) {
+ return getSema().ActOnCXXThrow(ThrowLoc, Sub);
}
/// \brief Build a new C++ default-argument expression.
@@ -1567,7 +1555,7 @@ public:
/// By default, builds a new default-argument expression, which does not
/// require any semantic analysis. Subclasses may override this routine to
/// provide different behavior.
- OwningExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
+ ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
ParmVarDecl *Param) {
return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
Param));
@@ -1577,12 +1565,12 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
+ ExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
SourceLocation LParenLoc,
QualType T,
SourceLocation RParenLoc) {
return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
- T.getAsOpaquePtr(), LParenLoc,
+ ParsedType::make(T), LParenLoc,
MultiExprArg(getSema(), 0, 0),
0, RParenLoc);
}
@@ -1591,7 +1579,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
+ ExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
bool UseGlobal,
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
@@ -1600,7 +1588,7 @@ public:
QualType AllocType,
SourceLocation TypeLoc,
SourceRange TypeRange,
- ExprArg ArraySize,
+ Expr *ArraySize,
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
@@ -1612,7 +1600,7 @@ public:
AllocType,
TypeLoc,
TypeRange,
- move(ArraySize),
+ ArraySize,
ConstructorLParen,
move(ConstructorArgs),
ConstructorRParen);
@@ -1622,25 +1610,25 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
+ ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
bool IsGlobalDelete,
bool IsArrayForm,
- ExprArg Operand) {
+ Expr *Operand) {
return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
- move(Operand));
+ Operand);
}
/// \brief Build a new unary type trait expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
+ ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
SourceLocation StartLoc,
SourceLocation LParenLoc,
QualType T,
SourceLocation RParenLoc) {
return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
- T.getAsOpaquePtr(), RParenLoc);
+ ParsedType::make(T), RParenLoc);
}
/// \brief Build a new (previously unresolved) declaration reference
@@ -1648,27 +1636,26 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
+ ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
SourceRange QualifierRange,
- DeclarationName Name,
- SourceLocation Location,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
CXXScopeSpec SS;
SS.setRange(QualifierRange);
SS.setScopeRep(NNS);
if (TemplateArgs)
- return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
+ return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo,
*TemplateArgs);
- return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
+ return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo);
}
/// \brief Build a new template-id expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
+ ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
LookupResult &R,
bool RequiresADL,
const TemplateArgumentListInfo &TemplateArgs) {
@@ -1679,32 +1666,35 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXConstructExpr(QualType T,
+ ExprResult RebuildCXXConstructExpr(QualType T,
SourceLocation Loc,
CXXConstructorDecl *Constructor,
bool IsElidable,
- MultiExprArg Args) {
- ASTOwningVector<&ActionBase::DeleteExpr> ConvertedArgs(SemaRef);
+ MultiExprArg Args,
+ bool RequiresZeroInit,
+ CXXConstructExpr::ConstructionKind ConstructKind) {
+ ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc,
ConvertedArgs))
- return getSema().ExprError();
+ return ExprError();
return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
- move_arg(ConvertedArgs));
+ move_arg(ConvertedArgs),
+ RequiresZeroInit, ConstructKind);
}
/// \brief Build a new object-construction expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
+ ExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
QualType T,
SourceLocation LParenLoc,
MultiExprArg Args,
SourceLocation *Commas,
SourceLocation RParenLoc) {
return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
- T.getAsOpaquePtr(),
+ ParsedType::make(T),
LParenLoc,
move(Args),
Commas,
@@ -1715,7 +1705,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
+ ExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
QualType T,
SourceLocation LParenLoc,
MultiExprArg Args,
@@ -1723,7 +1713,7 @@ public:
SourceLocation RParenLoc) {
return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
/*FIXME*/LParenLoc),
- T.getAsOpaquePtr(),
+ ParsedType::make(T),
LParenLoc,
move(Args),
Commas,
@@ -1734,31 +1724,31 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
+ ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
QualType BaseType,
bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *FirstQualifierInScope,
- DeclarationName Name,
- SourceLocation MemberLoc,
+ const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
CXXScopeSpec SS;
SS.setRange(QualifierRange);
SS.setScopeRep(Qualifier);
- return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+ return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
OperatorLoc, IsArrow,
SS, FirstQualifierInScope,
- Name, MemberLoc, TemplateArgs);
+ MemberNameInfo,
+ TemplateArgs);
}
/// \brief Build a new member reference expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildUnresolvedMemberExpr(ExprArg BaseE,
+ ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE,
QualType BaseType,
SourceLocation OperatorLoc,
bool IsArrow,
@@ -1771,7 +1761,7 @@ public:
SS.setRange(QualifierRange);
SS.setScopeRep(Qualifier);
- return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+ return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
OperatorLoc, IsArrow,
SS, FirstQualifierInScope,
R, TemplateArgs);
@@ -1781,7 +1771,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
+ ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
TypeSourceInfo *EncodeTypeInfo,
SourceLocation RParenLoc) {
return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
@@ -1789,7 +1779,7 @@ public:
}
/// \brief Build a new Objective-C class message.
- OwningExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
+ ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
Selector Sel,
ObjCMethodDecl *Method,
SourceLocation LBracLoc,
@@ -1803,15 +1793,14 @@ public:
}
/// \brief Build a new Objective-C instance message.
- OwningExprResult RebuildObjCMessageExpr(ExprArg Receiver,
+ ExprResult RebuildObjCMessageExpr(Expr *Receiver,
Selector Sel,
ObjCMethodDecl *Method,
SourceLocation LBracLoc,
MultiExprArg Args,
SourceLocation RBracLoc) {
- QualType ReceiverType = static_cast<Expr *>(Receiver.get())->getType();
- return SemaRef.BuildInstanceMessage(move(Receiver),
- ReceiverType,
+ return SemaRef.BuildInstanceMessage(Receiver,
+ Receiver->getType(),
/*SuperLoc=*/SourceLocation(),
Sel, Method, LBracLoc, RBracLoc,
move(Args));
@@ -1821,26 +1810,25 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildObjCIvarRefExpr(ExprArg BaseArg, ObjCIvarDecl *Ivar,
+ ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
SourceLocation IvarLoc,
bool IsArrow, bool IsFreeIvar) {
// FIXME: We lose track of the IsFreeIvar bit.
CXXScopeSpec SS;
- Expr *Base = BaseArg.takeAs<Expr>();
+ Expr *Base = BaseArg;
LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
Sema::LookupMemberName);
- OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+ ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IvarLoc,
- SS, DeclPtrTy(),
+ SS, 0,
false);
if (Result.isInvalid())
- return getSema().ExprError();
+ return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(getSema().Owned(Base),
- Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
/*FIXME:*/IvarLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@@ -1851,26 +1839,24 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildObjCPropertyRefExpr(ExprArg BaseArg,
+ ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
ObjCPropertyDecl *Property,
SourceLocation PropertyLoc) {
CXXScopeSpec SS;
- Expr *Base = BaseArg.takeAs<Expr>();
+ Expr *Base = BaseArg;
LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
Sema::LookupMemberName);
bool IsArrow = false;
- OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+ ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/PropertyLoc,
- SS, DeclPtrTy(),
- false);
+ SS, 0, false);
if (Result.isInvalid())
- return getSema().ExprError();
+ return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(getSema().Owned(Base),
- Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
/*FIXME:*/PropertyLoc, IsArrow,
SS,
/*FirstQualifierInScope=*/0,
@@ -1883,43 +1869,41 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildObjCImplicitSetterGetterRefExpr(
+ ExprResult RebuildObjCImplicitSetterGetterRefExpr(
ObjCMethodDecl *Getter,
QualType T,
ObjCMethodDecl *Setter,
SourceLocation NameLoc,
- ExprArg Base) {
+ Expr *Base) {
// Since these expressions can only be value-dependent, we do not need to
// perform semantic analysis again.
- return getSema().Owned(
+ return Owned(
new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
Setter,
NameLoc,
- Base.takeAs<Expr>()));
+ Base));
}
/// \brief Build a new Objective-C "isa" expression.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildObjCIsaExpr(ExprArg BaseArg, SourceLocation IsaLoc,
+ ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
bool IsArrow) {
CXXScopeSpec SS;
- Expr *Base = BaseArg.takeAs<Expr>();
+ Expr *Base = BaseArg;
LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
Sema::LookupMemberName);
- OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+ ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IsaLoc,
- SS, DeclPtrTy(),
- false);
+ SS, 0, false);
if (Result.isInvalid())
- return getSema().ExprError();
+ return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(getSema().Owned(Base),
- Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
/*FIXME:*/IsaLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@@ -1930,7 +1914,7 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
+ ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
MultiExprArg SubExprs,
SourceLocation RParenLoc) {
// Find the declaration for __builtin_shufflevector
@@ -1954,12 +1938,12 @@ public:
Subs, NumSubExprs,
Builtin->getCallResultType(),
RParenLoc);
- OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
+ ExprResult OwnedCall(SemaRef.Owned(TheCall));
// Type-check the __builtin_shufflevector expression.
- OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
+ ExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
if (Result.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
OwnedCall.release();
return move(Result);
@@ -1967,7 +1951,7 @@ public:
};
template<typename Derived>
-Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
+StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
if (!S)
return SemaRef.Owned(S);
@@ -1986,11 +1970,11 @@ Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
#define EXPR(Node, Parent) case Stmt::Node##Class:
#include "clang/AST/StmtNodes.inc"
{
- Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
+ ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
if (E.isInvalid())
- return getSema().StmtError();
+ return StmtError();
- return getSema().ActOnExprStmt(getSema().MakeFullExpr(E));
+ return getSema().ActOnExprStmt(getSema().MakeFullExpr(E.take()));
}
}
@@ -1999,7 +1983,7 @@ Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
template<typename Derived>
-Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
+ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
if (!E)
return SemaRef.Owned(E);
@@ -2094,12 +2078,13 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
}
template<typename Derived>
-DeclarationName
-TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
- SourceLocation Loc,
- QualType ObjectType) {
+DeclarationNameInfo
+TreeTransform<Derived>
+::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+ QualType ObjectType) {
+ DeclarationName Name = NameInfo.getName();
if (!Name)
- return Name;
+ return DeclarationNameInfo();
switch (Name.getNameKind()) {
case DeclarationName::Identifier:
@@ -2109,24 +2094,41 @@ TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
case DeclarationName::CXXOperatorName:
case DeclarationName::CXXLiteralOperatorName:
case DeclarationName::CXXUsingDirective:
- return Name;
+ return NameInfo;
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName: {
- TemporaryBase Rebase(*this, Loc, Name);
- QualType T = getDerived().TransformType(Name.getCXXNameType(),
- ObjectType);
- if (T.isNull())
- return DeclarationName();
+ TypeSourceInfo *NewTInfo;
+ CanQualType NewCanTy;
+ if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
+ NewTInfo = getDerived().TransformType(OldTInfo, ObjectType);
+ if (!NewTInfo)
+ return DeclarationNameInfo();
+ NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
+ }
+ else {
+ NewTInfo = 0;
+ TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
+ QualType NewT = getDerived().TransformType(Name.getCXXNameType(),
+ ObjectType);
+ if (NewT.isNull())
+ return DeclarationNameInfo();
+ NewCanTy = SemaRef.Context.getCanonicalType(NewT);
+ }
- return SemaRef.Context.DeclarationNames.getCXXSpecialName(
- Name.getNameKind(),
- SemaRef.Context.getCanonicalType(T));
+ DeclarationName NewName
+ = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
+ NewCanTy);
+ DeclarationNameInfo NewNameInfo(NameInfo);
+ NewNameInfo.setName(NewName);
+ NewNameInfo.setNamedTypeInfo(NewTInfo);
+ return NewNameInfo;
}
}
- return DeclarationName();
+ assert(0 && "Unknown name kind.");
+ return DeclarationNameInfo();
}
template<typename Derived>
@@ -2268,14 +2270,9 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
Expr *SourceExpr = Input.getSourceDeclExpression();
if (SourceExpr) {
EnterExpressionEvaluationContext Unevaluated(getSema(),
- Action::Unevaluated);
- Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
- if (E.isInvalid())
- SourceExpr = NULL;
- else {
- SourceExpr = E.takeAs<Expr>();
- SourceExpr->Retain();
- }
+ Sema::Unevaluated);
+ ExprResult E = getDerived().TransformExpr(SourceExpr);
+ SourceExpr = (E.isInvalid() ? 0 : E.take());
}
Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
@@ -2298,18 +2295,15 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
case TemplateArgument::Expression: {
// Template argument expressions are not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(getSema(),
- Action::Unevaluated);
+ Sema::Unevaluated);
Expr *InputExpr = Input.getSourceExpression();
if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
- Sema::OwningExprResult E
+ ExprResult E
= getDerived().TransformExpr(InputExpr);
if (E.isInvalid()) return true;
-
- Expr *ETaken = E.takeAs<Expr>();
- ETaken->Retain();
- Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+ Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
return false;
}
@@ -2631,7 +2625,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
Expr *Size = TL.getSizeExpr();
if (Size) {
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
}
NewTL.setSizeExpr(Size);
@@ -2679,14 +2673,14 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
return QualType();
// Array bounds are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- Sema::OwningExprResult SizeResult
+ ExprResult SizeResult
= getDerived().TransformExpr(T->getSizeExpr());
if (SizeResult.isInvalid())
return QualType();
- Expr *Size = static_cast<Expr*>(SizeResult.get());
+ Expr *Size = SizeResult.take();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
@@ -2694,13 +2688,12 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
Size != T->getSizeExpr()) {
Result = getDerived().RebuildVariableArrayType(ElementType,
T->getSizeModifier(),
- move(SizeResult),
+ Size,
T->getIndexTypeCVRQualifiers(),
TL.getBracketsRange());
if (Result.isNull())
return QualType();
}
- else SizeResult.take();
VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
NewTL.setLBracketLoc(TL.getLBracketLoc());
@@ -2721,9 +2714,9 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
return QualType();
// Array bounds are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- Sema::OwningExprResult SizeResult
+ ExprResult SizeResult
= getDerived().TransformExpr(T->getSizeExpr());
if (SizeResult.isInvalid())
return QualType();
@@ -2736,7 +2729,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
Size != T->getSizeExpr()) {
Result = getDerived().RebuildDependentSizedArrayType(ElementType,
T->getSizeModifier(),
- move(SizeResult),
+ Size,
T->getIndexTypeCVRQualifiers(),
TL.getBracketsRange());
if (Result.isNull())
@@ -2767,9 +2760,9 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
return QualType();
// Vector sizes are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+ ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
if (Size.isInvalid())
return QualType();
@@ -2778,12 +2771,11 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
ElementType != T->getElementType() ||
Size.get() != T->getSizeExpr()) {
Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
- move(Size),
+ Size.take(),
T->getAttributeLoc());
if (Result.isNull())
return QualType();
}
- else Size.take();
// Result might be dependent or not.
if (isa<DependentSizedExtVectorType>(Result)) {
@@ -2911,18 +2903,25 @@ QualType
TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL,
QualType ObjectType) {
- // Transform the parameters. We do this first for the benefit of template
- // instantiations, so that the ParmVarDecls get/ placed into the template
- // instantiation scope before we transform the function type.
+ // Transform the parameters and return type.
+ //
+ // We instantiate in source order, with the return type first followed by
+ // the parameters, because users tend to expect this (even if they shouldn't
+ // rely on it!).
+ //
+ // FIXME: When we implement late-specified return types, we'll need to
+ // instantiate the return tpe *after* the parameter types in that case,
+ // since the return type can then refer to the parameters themselves (via
+ // decltype, sizeof, etc.).
llvm::SmallVector<QualType, 4> ParamTypes;
llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
- if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
- return QualType();
-
FunctionProtoType *T = TL.getTypePtr();
QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
if (ResultType.isNull())
return QualType();
+
+ if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
+ return QualType();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
@@ -2932,7 +2931,8 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
ParamTypes.data(),
ParamTypes.size(),
T->isVariadic(),
- T->getTypeQuals());
+ T->getTypeQuals(),
+ T->getExtInfo());
if (Result.isNull())
return QualType();
}
@@ -3022,16 +3022,16 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
TypeOfExprTypeLoc TL,
QualType ObjectType) {
// typeof expressions are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- Sema::OwningExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
+ ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
if (E.isInvalid())
return QualType();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
E.get() != TL.getUnderlyingExpr()) {
- Result = getDerived().RebuildTypeOfExprType(move(E));
+ Result = getDerived().RebuildTypeOfExprType(E.get());
if (Result.isNull())
return QualType();
}
@@ -3077,16 +3077,16 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
DecltypeType *T = TL.getTypePtr();
// decltype expressions are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
+ ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
if (E.isInvalid())
return QualType();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
E.get() != T->getUnderlyingExpr()) {
- Result = getDerived().RebuildDecltypeType(move(E));
+ Result = getDerived().RebuildDecltypeType(E.get());
if (Result.isNull())
return QualType();
}
@@ -3432,33 +3432,45 @@ TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
// Statement transformation
//===----------------------------------------------------------------------===//
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
return SemaRef.Owned(S->Retain());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
return getDerived().TransformCompoundStmt(S, false);
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
bool IsStmtExpr) {
+ bool SubStmtInvalid = false;
bool SubStmtChanged = false;
- ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
+ ASTOwningVector<Stmt*> Statements(getSema());
for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
B != BEnd; ++B) {
- OwningStmtResult Result = getDerived().TransformStmt(*B);
- if (Result.isInvalid())
- return getSema().StmtError();
+ StmtResult Result = getDerived().TransformStmt(*B);
+ if (Result.isInvalid()) {
+ // Immediately fail if this was a DeclStmt, since it's very
+ // likely that this will cause problems for future statements.
+ if (isa<DeclStmt>(*B))
+ return StmtError();
+
+ // Otherwise, just keep processing substatements and fail later.
+ SubStmtInvalid = true;
+ continue;
+ }
SubStmtChanged = SubStmtChanged || Result.get() != *B;
Statements.push_back(Result.takeAs<Stmt>());
}
+ if (SubStmtInvalid)
+ return StmtError();
+
if (!getDerived().AlwaysRebuild() &&
!SubStmtChanged)
return SemaRef.Owned(S->Retain());
@@ -3470,75 +3482,75 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
- OwningExprResult LHS(SemaRef), RHS(SemaRef);
+ ExprResult LHS, RHS;
{
// The case value expressions are not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
// Transform the left-hand case value.
LHS = getDerived().TransformExpr(S->getLHS());
if (LHS.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the right-hand case value (for the GNU case-range extension).
RHS = getDerived().TransformExpr(S->getRHS());
if (RHS.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
}
// Build the case statement.
// Case statements are always rebuilt so that they will attached to their
// transformed switch statement.
- OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
- move(LHS),
+ StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
+ LHS.get(),
S->getEllipsisLoc(),
- move(RHS),
+ RHS.get(),
S->getColonLoc());
if (Case.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the statement following the case
- OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
if (SubStmt.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Attach the body to the case statement
- return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
+ return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
// Transform the statement following the default case
- OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
if (SubStmt.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Default statements are always rebuilt
return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
- move(SubStmt));
+ SubStmt.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
- OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
if (SubStmt.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// FIXME: Pass the real colon location in.
SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
- move(SubStmt));
+ SubStmt.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
// Transform the condition
- OwningExprResult Cond(SemaRef);
+ ExprResult Cond;
VarDecl *ConditionVar = 0;
if (S->getConditionVariable()) {
ConditionVar
@@ -3547,56 +3559,56 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
S->getConditionVariable()->getLocation(),
S->getConditionVariable()));
if (!ConditionVar)
- return SemaRef.StmtError();
+ return StmtError();
} else {
Cond = getDerived().TransformExpr(S->getCond());
if (Cond.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Convert the condition to a boolean value.
if (S->getCond()) {
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0,
+ ExprResult CondE = getSema().ActOnBooleanCondition(0,
S->getIfLoc(),
- move(Cond));
+ Cond.get());
if (CondE.isInvalid())
- return getSema().StmtError();
+ return StmtError();
- Cond = move(CondE);
+ Cond = CondE.get();
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
- return SemaRef.StmtError();
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ return StmtError();
// Transform the "then" branch.
- OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
+ StmtResult Then = getDerived().TransformStmt(S->getThen());
if (Then.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the "else" branch.
- OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
+ StmtResult Else = getDerived().TransformStmt(S->getElse());
if (Else.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
- FullCond->get() == S->getCond() &&
+ FullCond.get() == S->getCond() &&
ConditionVar == S->getConditionVariable() &&
Then.get() == S->getThen() &&
Else.get() == S->getElse())
return SemaRef.Owned(S->Retain());
return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
- move(Then),
- S->getElseLoc(), move(Else));
+ Then.get(),
+ S->getElseLoc(), Else.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
// Transform the condition.
- OwningExprResult Cond(SemaRef);
+ ExprResult Cond;
VarDecl *ConditionVar = 0;
if (S->getConditionVariable()) {
ConditionVar
@@ -3605,36 +3617,36 @@ TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
S->getConditionVariable()->getLocation(),
S->getConditionVariable()));
if (!ConditionVar)
- return SemaRef.StmtError();
+ return StmtError();
} else {
Cond = getDerived().TransformExpr(S->getCond());
if (Cond.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
}
// Rebuild the switch statement.
- OwningStmtResult Switch
- = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), move(Cond),
+ StmtResult Switch
+ = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
ConditionVar);
if (Switch.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the body of the switch statement.
- OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+ StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Complete the switch statement.
- return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
- move(Body));
+ return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
+ Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
// Transform the condition
- OwningExprResult Cond(SemaRef);
+ ExprResult Cond;
VarDecl *ConditionVar = 0;
if (S->getConditionVariable()) {
ConditionVar
@@ -3643,76 +3655,76 @@ TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
S->getConditionVariable()->getLocation(),
S->getConditionVariable()));
if (!ConditionVar)
- return SemaRef.StmtError();
+ return StmtError();
} else {
Cond = getDerived().TransformExpr(S->getCond());
if (Cond.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (S->getCond()) {
// Convert the condition to a boolean value.
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0,
+ ExprResult CondE = getSema().ActOnBooleanCondition(0,
S->getWhileLoc(),
- move(Cond));
+ Cond.get());
if (CondE.isInvalid())
- return getSema().StmtError();
- Cond = move(CondE);
+ return StmtError();
+ Cond = CondE;
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
- return SemaRef.StmtError();
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ return StmtError();
// Transform the body
- OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+ StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
- FullCond->get() == S->getCond() &&
+ FullCond.get() == S->getCond() &&
ConditionVar == S->getConditionVariable() &&
Body.get() == S->getBody())
- return SemaRef.Owned(S->Retain());
+ return Owned(S);
return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
- ConditionVar, move(Body));
+ ConditionVar, Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
// Transform the body
- OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+ StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the condition
- OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
+ ExprResult Cond = getDerived().TransformExpr(S->getCond());
if (Cond.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
Cond.get() == S->getCond() &&
Body.get() == S->getBody())
return SemaRef.Owned(S->Retain());
- return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
- /*FIXME:*/S->getWhileLoc(), move(Cond),
+ return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
+ /*FIXME:*/S->getWhileLoc(), Cond.get(),
S->getRParenLoc());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
// Transform the initialization statement
- OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
+ StmtResult Init = getDerived().TransformStmt(S->getInit());
if (Init.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the condition
- OwningExprResult Cond(SemaRef);
+ ExprResult Cond;
VarDecl *ConditionVar = 0;
if (S->getConditionVariable()) {
ConditionVar
@@ -3721,57 +3733,57 @@ TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
S->getConditionVariable()->getLocation(),
S->getConditionVariable()));
if (!ConditionVar)
- return SemaRef.StmtError();
+ return StmtError();
} else {
Cond = getDerived().TransformExpr(S->getCond());
if (Cond.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (S->getCond()) {
// Convert the condition to a boolean value.
- OwningExprResult CondE = getSema().ActOnBooleanCondition(0,
+ ExprResult CondE = getSema().ActOnBooleanCondition(0,
S->getForLoc(),
- move(Cond));
+ Cond.get());
if (CondE.isInvalid())
- return getSema().StmtError();
+ return StmtError();
- Cond = move(CondE);
+ Cond = CondE.get();
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
- if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
- return SemaRef.StmtError();
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ return StmtError();
// Transform the increment
- OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
+ ExprResult Inc = getDerived().TransformExpr(S->getInc());
if (Inc.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
- Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc));
- if (S->getInc() && !FullInc->get())
- return SemaRef.StmtError();
+ Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc.get()));
+ if (S->getInc() && !FullInc.get())
+ return StmtError();
// Transform the body
- OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+ StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
Init.get() == S->getInit() &&
- FullCond->get() == S->getCond() &&
+ FullCond.get() == S->getCond() &&
Inc.get() == S->getInc() &&
Body.get() == S->getBody())
return SemaRef.Owned(S->Retain());
return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
- move(Init), FullCond, ConditionVar,
- FullInc, S->getRParenLoc(), move(Body));
+ Init.get(), FullCond, ConditionVar,
+ FullInc, S->getRParenLoc(), Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
// Goto statements must always be rebuilt, to resolve the label.
return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
@@ -3779,46 +3791,46 @@ TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
- OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
+ ExprResult Target = getDerived().TransformExpr(S->getTarget());
if (Target.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
Target.get() == S->getTarget())
return SemaRef.Owned(S->Retain());
return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
- move(Target));
+ Target.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
return SemaRef.Owned(S->Retain());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
return SemaRef.Owned(S->Retain());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
- Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
+ ExprResult Result = getDerived().TransformExpr(S->getRetValue());
if (Result.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// FIXME: We always rebuild the return statement because there is no way
// to tell whether the return type of the function has changed.
- return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
+ return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
bool DeclChanged = false;
llvm::SmallVector<Decl *, 4> Decls;
@@ -3827,7 +3839,7 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
*D);
if (!Transformed)
- return SemaRef.StmtError();
+ return StmtError();
if (Transformed != *D)
DeclChanged = true;
@@ -3843,22 +3855,22 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
assert(false && "SwitchCase is abstract and cannot be transformed");
return SemaRef.Owned(S->Retain());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
- ASTOwningVector<&ActionBase::DeleteExpr> Constraints(getSema());
- ASTOwningVector<&ActionBase::DeleteExpr> Exprs(getSema());
+ ASTOwningVector<Expr*> Constraints(getSema());
+ ASTOwningVector<Expr*> Exprs(getSema());
llvm::SmallVector<IdentifierInfo *, 4> Names;
- OwningExprResult AsmString(SemaRef);
- ASTOwningVector<&ActionBase::DeleteExpr> Clobbers(getSema());
+ ExprResult AsmString;
+ ASTOwningVector<Expr*> Clobbers(getSema());
bool ExprsChanged = false;
@@ -3871,13 +3883,13 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
// Transform the output expr.
Expr *OutputExpr = S->getOutputExpr(I);
- OwningExprResult Result = getDerived().TransformExpr(OutputExpr);
+ ExprResult Result = getDerived().TransformExpr(OutputExpr);
if (Result.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
ExprsChanged |= Result.get() != OutputExpr;
- Exprs.push_back(Result.takeAs<Expr>());
+ Exprs.push_back(Result.get());
}
// Go through the inputs.
@@ -3889,13 +3901,13 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
// Transform the input expr.
Expr *InputExpr = S->getInputExpr(I);
- OwningExprResult Result = getDerived().TransformExpr(InputExpr);
+ ExprResult Result = getDerived().TransformExpr(InputExpr);
if (Result.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
ExprsChanged |= Result.get() != InputExpr;
- Exprs.push_back(Result.takeAs<Expr>());
+ Exprs.push_back(Result.get());
}
if (!getDerived().AlwaysRebuild() && !ExprsChanged)
@@ -3916,7 +3928,7 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
Names.data(),
move_arg(Constraints),
move_arg(Exprs),
- move(AsmString),
+ AsmString.get(),
move_arg(Clobbers),
S->getRParenLoc(),
S->isMSAsm());
@@ -3924,31 +3936,31 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
// Transform the body of the @try.
- OwningStmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
+ StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
if (TryBody.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the @catch statements (if present).
bool AnyCatchChanged = false;
- ASTOwningVector<&ActionBase::DeleteStmt> CatchStmts(SemaRef);
+ ASTOwningVector<Stmt*> CatchStmts(SemaRef);
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
- OwningStmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
+ StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
if (Catch.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
if (Catch.get() != S->getCatchStmt(I))
AnyCatchChanged = true;
CatchStmts.push_back(Catch.release());
}
// Transform the @finally statement (if present).
- OwningStmtResult Finally(SemaRef);
+ StmtResult Finally;
if (S->getFinallyStmt()) {
Finally = getDerived().TransformStmt(S->getFinallyStmt());
if (Finally.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
}
// If nothing changed, just retain this statement.
@@ -3959,12 +3971,12 @@ TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
return SemaRef.Owned(S->Retain());
// Build a new statement.
- return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), move(TryBody),
- move_arg(CatchStmts), move(Finally));
+ return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
+ move_arg(CatchStmts), Finally.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
// Transform the @catch parameter, if there is one.
VarDecl *Var = 0;
@@ -3973,7 +3985,7 @@ TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
if (FromVar->getTypeSourceInfo()) {
TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
if (!TSInfo)
- return SemaRef.StmtError();
+ return StmtError();
}
QualType T;
@@ -3982,30 +3994,30 @@ TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
else {
T = getDerived().TransformType(FromVar->getType());
if (T.isNull())
- return SemaRef.StmtError();
+ return StmtError();
}
Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
if (!Var)
- return SemaRef.StmtError();
+ return StmtError();
}
- OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
+ StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
S->getRParenLoc(),
- Var, move(Body));
+ Var, Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
// Transform the body.
- OwningStmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
+ StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// If nothing changed, just retain this statement.
if (!getDerived().AlwaysRebuild() &&
@@ -4014,39 +4026,39 @@ TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
// Build a new statement.
return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
- move(Body));
+ Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- OwningExprResult Operand(SemaRef);
+ ExprResult Operand;
if (S->getThrowExpr()) {
Operand = getDerived().TransformExpr(S->getThrowExpr());
if (Operand.isInvalid())
- return getSema().StmtError();
+ return StmtError();
}
if (!getDerived().AlwaysRebuild() &&
Operand.get() == S->getThrowExpr())
return getSema().Owned(S->Retain());
- return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), move(Operand));
+ return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
ObjCAtSynchronizedStmt *S) {
// Transform the object we are locking.
- OwningExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
+ ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
if (Object.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the body.
- OwningStmtResult Body = getDerived().TransformStmt(S->getSynchBody());
+ StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// If nothing change, just retain the current statement.
if (!getDerived().AlwaysRebuild() &&
@@ -4056,27 +4068,27 @@ TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
// Build a new statement.
return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
- move(Object), move(Body));
+ Object.get(), Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformObjCForCollectionStmt(
ObjCForCollectionStmt *S) {
// Transform the element statement.
- OwningStmtResult Element = getDerived().TransformStmt(S->getElement());
+ StmtResult Element = getDerived().TransformStmt(S->getElement());
if (Element.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the collection expression.
- OwningExprResult Collection = getDerived().TransformExpr(S->getCollection());
+ ExprResult Collection = getDerived().TransformExpr(S->getCollection());
if (Collection.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the body.
- OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+ StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// If nothing changed, just retain this statement.
if (!getDerived().AlwaysRebuild() &&
@@ -4088,15 +4100,15 @@ TreeTransform<Derived>::TransformObjCForCollectionStmt(
// Build a new statement.
return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
/*FIXME:*/S->getForLoc(),
- move(Element),
- move(Collection),
+ Element.get(),
+ Collection.get(),
S->getRParenLoc(),
- move(Body));
+ Body.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
// Transform the exception declaration, if any.
VarDecl *Var = 0;
@@ -4107,7 +4119,7 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
QualType T = getDerived().TransformType(ExceptionDecl->getType());
if (T.isNull())
- return SemaRef.StmtError();
+ return StmtError();
Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
T,
@@ -4116,20 +4128,14 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
ExceptionDecl->getLocation(),
/*FIXME: Inaccurate*/
SourceRange(ExceptionDecl->getLocation()));
- if (!Var || Var->isInvalidDecl()) {
- if (Var)
- Var->Destroy(SemaRef.Context);
- return SemaRef.StmtError();
- }
+ if (!Var || Var->isInvalidDecl())
+ return StmtError();
}
// Transform the actual exception handler.
- OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
- if (Handler.isInvalid()) {
- if (Var)
- Var->Destroy(SemaRef.Context);
- return SemaRef.StmtError();
- }
+ StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
+ if (Handler.isInvalid())
+ return StmtError();
if (!getDerived().AlwaysRebuild() &&
!Var &&
@@ -4138,26 +4144,26 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
Var,
- move(Handler));
+ Handler.get());
}
template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
// Transform the try block itself.
- OwningStmtResult TryBlock
+ StmtResult TryBlock
= getDerived().TransformCompoundStmt(S->getTryBlock());
if (TryBlock.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
// Transform the handlers.
bool HandlerChanged = false;
- ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
+ ASTOwningVector<Stmt*> Handlers(SemaRef);
for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
- OwningStmtResult Handler
+ StmtResult Handler
= getDerived().TransformCXXCatchStmt(S->getHandler(I));
if (Handler.isInvalid())
- return SemaRef.StmtError();
+ return StmtError();
HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
Handlers.push_back(Handler.takeAs<Stmt>());
@@ -4168,7 +4174,7 @@ TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
!HandlerChanged)
return SemaRef.Owned(S->Retain());
- return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
+ return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
move_arg(Handlers));
}
@@ -4176,32 +4182,40 @@ TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
// Expression transformation
//===----------------------------------------------------------------------===//
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
NestedNameSpecifier *Qualifier = 0;
if (E->getQualifier()) {
Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange());
if (!Qualifier)
- return SemaRef.ExprError();
+ return ExprError();
}
ValueDecl *ND
= cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
E->getDecl()));
if (!ND)
- return SemaRef.ExprError();
+ return ExprError();
- if (!getDerived().AlwaysRebuild() &&
+ DeclarationNameInfo NameInfo = E->getNameInfo();
+ if (NameInfo.getName()) {
+ NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+ if (!NameInfo.getName())
+ return ExprError();
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
Qualifier == E->getQualifier() &&
ND == E->getDecl() &&
- !E->hasExplicitTemplateArgumentList()) {
+ NameInfo.getName() == E->getDecl()->getDeclName() &&
+ !E->hasExplicitTemplateArgs()) {
// Mark it referenced in the new context regardless.
// FIXME: this is a bit instantiation-specific.
@@ -4211,88 +4225,88 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
}
TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
- if (E->hasExplicitTemplateArgumentList()) {
+ if (E->hasExplicitTemplateArgs()) {
TemplateArgs = &TransArgs;
TransArgs.setLAngleLoc(E->getLAngleLoc());
TransArgs.setRAngleLoc(E->getRAngleLoc());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
}
return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
- ND, E->getLocation(), TemplateArgs);
+ ND, NameInfo, TemplateArgs);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
+ return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
E->getRParen());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
return SemaRef.Owned(E->Retain());
return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
E->getOpcode(),
- move(SubExpr));
+ SubExpr.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
// Transform the type.
TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
if (!Type)
- return getSema().ExprError();
+ return ExprError();
// Transform all of the components into components similar to what the
// parser uses.
@@ -4301,7 +4315,7 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
// the fields again. However, __builtin_offsetof is rare enough in
// template code that we don't care.
bool ExprChanged = false;
- typedef Action::OffsetOfComponent Component;
+ typedef Sema::OffsetOfComponent Component;
typedef OffsetOfExpr::OffsetOfNode Node;
llvm::SmallVector<Component, 4> Components;
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
@@ -4313,13 +4327,13 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
switch (ON.getKind()) {
case Node::Array: {
Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
- OwningExprResult Index = getDerived().TransformExpr(FromIndex);
+ ExprResult Index = getDerived().TransformExpr(FromIndex);
if (Index.isInvalid())
- return getSema().ExprError();
+ return ExprError();
ExprChanged = ExprChanged || Index.get() != FromIndex;
Comp.isBrackets = true;
- Comp.U.E = Index.takeAs<Expr>(); // FIXME: leaked
+ Comp.U.E = Index.get();
break;
}
@@ -4353,14 +4367,14 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
if (E->isArgumentType()) {
TypeSourceInfo *OldT = E->getArgumentTypeInfo();
TypeSourceInfo *NewT = getDerived().TransformType(OldT);
if (!NewT)
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() && OldT == NewT)
return SemaRef.Owned(E->Retain());
@@ -4370,36 +4384,36 @@ TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
E->getSourceRange());
}
- Sema::OwningExprResult SubExpr(SemaRef);
+ ExprResult SubExpr;
{
// C++0x [expr.sizeof]p1:
// The operand is either an expression, which is an unevaluated operand
// [...]
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
return SemaRef.Owned(E->Retain());
}
- return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
+ return getDerived().RebuildSizeOfAlignOf(SubExpr.get(), E->getOperatorLoc(),
E->isSizeOf(),
E->getSourceRange());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
- OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ ExprResult LHS = getDerived().TransformExpr(E->getLHS());
if (LHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ ExprResult RHS = getDerived().TransformExpr(E->getRHS());
if (RHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
@@ -4407,35 +4421,35 @@ TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
RHS.get() == E->getRHS())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildArraySubscriptExpr(move(LHS),
+ return getDerived().RebuildArraySubscriptExpr(LHS.get(),
/*FIXME:*/E->getLHS()->getLocStart(),
- move(RHS),
+ RHS.get(),
E->getRBracketLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
// Transform the callee.
- OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+ ExprResult Callee = getDerived().TransformExpr(E->getCallee());
if (Callee.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// Transform arguments.
bool ArgChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
- OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+ ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
if (Arg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// FIXME: Wrong source location information for the ','.
FakeCommaLocs.push_back(
SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
- Args.push_back(Arg.takeAs<Expr>());
+ Args.push_back(Arg.get());
}
if (!getDerived().AlwaysRebuild() &&
@@ -4446,18 +4460,18 @@ TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
// FIXME: Wrong source location information for the '('.
SourceLocation FakeLParenLoc
= ((Expr *)Callee.get())->getSourceRange().getBegin();
- return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
+ return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
move_arg(Args),
FakeCommaLocs.data(),
E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
NestedNameSpecifier *Qualifier = 0;
if (E->hasQualifier()) {
@@ -4465,14 +4479,14 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange());
if (Qualifier == 0)
- return SemaRef.ExprError();
+ return ExprError();
}
ValueDecl *Member
= cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
E->getMemberDecl()));
if (!Member)
- return SemaRef.ExprError();
+ return ExprError();
NamedDecl *FoundDecl = E->getFoundDecl();
if (FoundDecl == E->getMemberDecl()) {
@@ -4481,7 +4495,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
FoundDecl = cast_or_null<NamedDecl>(
getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
if (!FoundDecl)
- return SemaRef.ExprError();
+ return ExprError();
}
if (!getDerived().AlwaysRebuild() &&
@@ -4489,7 +4503,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Qualifier == E->getQualifier() &&
Member == E->getMemberDecl() &&
FoundDecl == E->getFoundDecl() &&
- !E->hasExplicitTemplateArgumentList()) {
+ !E->hasExplicitTemplateArgs()) {
// Mark it referenced in the new context regardless.
// FIXME: this is a bit instantiation-specific.
@@ -4498,13 +4512,13 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
}
TemplateArgumentListInfo TransArgs;
- if (E->hasExplicitTemplateArgumentList()) {
+ if (E->hasExplicitTemplateArgs()) {
TransArgs.setLAngleLoc(E->getLAngleLoc());
TransArgs.setRAngleLoc(E->getRAngleLoc());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
}
@@ -4519,28 +4533,28 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
// nested-name-qualifier (and therefore could do the lookup).
NamedDecl *FirstQualifierInScope = 0;
- return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
+ return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
E->isArrow(),
Qualifier,
E->getQualifierRange(),
- E->getMemberLoc(),
+ E->getMemberNameInfo(),
Member,
FoundDecl,
- (E->hasExplicitTemplateArgumentList()
+ (E->hasExplicitTemplateArgs()
? &TransArgs : 0),
FirstQualifierInScope);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
- OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ ExprResult LHS = getDerived().TransformExpr(E->getLHS());
if (LHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ ExprResult RHS = getDerived().TransformExpr(E->getRHS());
if (RHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
LHS.get() == E->getLHS() &&
@@ -4548,30 +4562,30 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
return SemaRef.Owned(E->Retain());
return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
- move(LHS), move(RHS));
+ LHS.get(), RHS.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCompoundAssignOperator(
CompoundAssignOperator *E) {
return getDerived().TransformBinaryOperator(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
- OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+ ExprResult Cond = getDerived().TransformExpr(E->getCond());
if (Cond.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ ExprResult LHS = getDerived().TransformExpr(E->getLHS());
if (LHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ ExprResult RHS = getDerived().TransformExpr(E->getRHS());
if (RHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
Cond.get() == E->getCond() &&
@@ -4579,15 +4593,15 @@ TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
RHS.get() == E->getRHS())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildConditionalOperator(move(Cond),
+ return getDerived().RebuildConditionalOperator(Cond.get(),
E->getQuestionLoc(),
- move(LHS),
+ LHS.get(),
E->getColonLoc(),
- move(RHS));
+ RHS.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
// Implicit casts are eliminated during transformation, since they
// will be recomputed by semantic analysis after transformation.
@@ -4595,7 +4609,7 @@ TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
TypeSourceInfo *OldT;
TypeSourceInfo *NewT;
@@ -4608,13 +4622,13 @@ TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
OldT = E->getTypeInfoAsWritten();
NewT = getDerived().TransformType(OldT);
if (!NewT)
- return SemaRef.ExprError();
+ return ExprError();
}
- OwningExprResult SubExpr
+ ExprResult SubExpr
= getDerived().TransformExpr(E->getSubExprAsWritten());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
OldT == NewT &&
@@ -4624,20 +4638,20 @@ TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
NewT,
E->getRParenLoc(),
- move(SubExpr));
+ SubExpr.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
TypeSourceInfo *OldT = E->getTypeSourceInfo();
TypeSourceInfo *NewT = getDerived().TransformType(OldT);
if (!NewT)
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
+ ExprResult Init = getDerived().TransformExpr(E->getInitializer());
if (Init.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
OldT == NewT &&
@@ -4650,15 +4664,15 @@ TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
/*FIXME:*/E->getInitializer()->getLocEnd(),
- move(Init));
+ Init.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
@@ -4667,24 +4681,24 @@ TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
// FIXME: Bad source location
SourceLocation FakeOperatorLoc
= SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
- return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
+ return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc,
E->getAccessorLoc(),
E->getAccessor());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
bool InitChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+ ASTOwningVector<Expr*, 4> Inits(SemaRef);
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
- OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
+ ExprResult Init = getDerived().TransformExpr(E->getInit(I));
if (Init.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
InitChanged = InitChanged || Init.get() != E->getInit(I);
- Inits.push_back(Init.takeAs<Expr>());
+ Inits.push_back(Init.get());
}
if (!getDerived().AlwaysRebuild() && !InitChanged)
@@ -4695,17 +4709,17 @@ TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Designation Desig;
// transform the initializer value
- OwningExprResult Init = getDerived().TransformExpr(E->getInit());
+ ExprResult Init = getDerived().TransformExpr(E->getInit());
if (Init.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// transform the designators.
- ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+ ASTOwningVector<Expr*, 4> ArrayExprs(SemaRef);
bool ExprChanged = false;
for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
DEnd = E->designators_end();
@@ -4718,9 +4732,9 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
}
if (D->isArrayDesignator()) {
- OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
+ ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
if (Index.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
Desig.AddDesignator(Designator::getArray(Index.get(),
D->getLBracketLoc()));
@@ -4731,14 +4745,14 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
}
assert(D->isArrayRangeDesignator() && "New kind of designator?");
- OwningExprResult Start
+ ExprResult Start
= getDerived().TransformExpr(E->getArrayRangeStart(*D));
if (Start.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
+ ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
if (End.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
Desig.AddDesignator(Designator::getArrayRange(Start.get(),
End.get(),
@@ -4759,11 +4773,11 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
E->getEqualOrColonLoc(),
- E->usesGNUSyntax(), move(Init));
+ E->usesGNUSyntax(), Init.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformImplicitValueInitExpr(
ImplicitValueInitExpr *E) {
TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
@@ -4772,7 +4786,7 @@ TreeTransform<Derived>::TransformImplicitValueInitExpr(
// need to transform the type?
QualType T = getDerived().TransformType(E->getType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
T == E->getType())
@@ -4782,44 +4796,37 @@ TreeTransform<Derived>::TransformImplicitValueInitExpr(
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
- // FIXME: Do we want the type as written?
- QualType T;
+ TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
+ if (!TInfo)
+ return ExprError();
- {
- // FIXME: Source location isn't quite accurate.
- TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
- T = getDerived().TransformType(E->getType());
- if (T.isNull())
- return SemaRef.ExprError();
- }
-
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
- T == E->getType() &&
+ TInfo == E->getWrittenTypeInfo() &&
SubExpr.get() == E->getSubExpr())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
- T, E->getRParenLoc());
+ return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
+ TInfo, E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+ ASTOwningVector<Expr*, 4> Inits(SemaRef);
for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
- OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
+ ExprResult Init = getDerived().TransformExpr(E->getExpr(I));
if (Init.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
- Inits.push_back(Init.takeAs<Expr>());
+ Inits.push_back(Init.get());
}
return getDerived().RebuildParenListExpr(E->getLParenLoc(),
@@ -4833,69 +4840,67 @@ TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
/// rebuilds the expression, so that the label identifier can be resolved to
/// the corresponding label statement by semantic analysis.
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
E->getLabel());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
- OwningStmtResult SubStmt
+ StmtResult SubStmt
= getDerived().TransformCompoundStmt(E->getSubStmt(), true);
if (SubStmt.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
SubStmt.get() == E->getSubStmt())
return SemaRef.Owned(E->Retain());
return getDerived().RebuildStmtExpr(E->getLParenLoc(),
- move(SubStmt),
+ SubStmt.get(),
E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
- QualType T1, T2;
- {
- // FIXME: Source location isn't quite accurate.
- TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
-
- T1 = getDerived().TransformType(E->getArgType1());
- if (T1.isNull())
- return SemaRef.ExprError();
+ TypeSourceInfo *TInfo1;
+ TypeSourceInfo *TInfo2;
+
+ TInfo1 = getDerived().TransformType(E->getArgTInfo1());
+ if (!TInfo1)
+ return ExprError();
- T2 = getDerived().TransformType(E->getArgType2());
- if (T2.isNull())
- return SemaRef.ExprError();
- }
+ TInfo2 = getDerived().TransformType(E->getArgTInfo2());
+ if (!TInfo2)
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
- T1 == E->getArgType1() &&
- T2 == E->getArgType2())
+ TInfo1 == E->getArgTInfo1() &&
+ TInfo2 == E->getArgTInfo2())
return SemaRef.Owned(E->Retain());
return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
- T1, T2, E->getRParenLoc());
+ TInfo1, TInfo2,
+ E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
- OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+ ExprResult Cond = getDerived().TransformExpr(E->getCond());
if (Cond.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ ExprResult LHS = getDerived().TransformExpr(E->getLHS());
if (LHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ ExprResult RHS = getDerived().TransformExpr(E->getRHS());
if (RHS.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
Cond.get() == E->getCond() &&
@@ -4904,18 +4909,18 @@ TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
return SemaRef.Owned(E->Retain());
return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
- move(Cond), move(LHS), move(RHS),
+ Cond.get(), LHS.get(), RHS.get(),
E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
switch (E->getOperator()) {
case OO_New:
@@ -4923,16 +4928,16 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
case OO_Array_New:
case OO_Array_Delete:
llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
- return SemaRef.ExprError();
+ return ExprError();
case OO_Call: {
// This is a call to an object's operator().
assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
// Transform the object itself.
- OwningExprResult Object = getDerived().TransformExpr(E->getArg(0));
+ ExprResult Object = getDerived().TransformExpr(E->getArg(0));
if (Object.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// FIXME: Poor location information
SourceLocation FakeLParenLoc
@@ -4940,15 +4945,15 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
static_cast<Expr *>(Object.get())->getLocEnd());
// Transform the call arguments.
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) {
if (getDerived().DropCallArgument(E->getArg(I)))
break;
- OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+ ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
if (Arg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// FIXME: Poor source location information.
SourceLocation FakeCommaLoc
@@ -4958,7 +4963,7 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
Args.push_back(Arg.release());
}
- return getDerived().RebuildCallExpr(move(Object), FakeLParenLoc,
+ return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc,
move_arg(Args),
FakeCommaLocs.data(),
E->getLocEnd());
@@ -4974,27 +4979,27 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
case OO_Conditional:
llvm_unreachable("conditional operator is not actually overloadable");
- return SemaRef.ExprError();
+ return ExprError();
case OO_None:
case NUM_OVERLOADED_OPERATORS:
llvm_unreachable("not an overloaded operator?");
- return SemaRef.ExprError();
+ return ExprError();
}
- OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+ ExprResult Callee = getDerived().TransformExpr(E->getCallee());
if (Callee.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
+ ExprResult First = getDerived().TransformExpr(E->getArg(0));
if (First.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- OwningExprResult Second(SemaRef);
+ ExprResult Second;
if (E->getNumArgs() == 2) {
Second = getDerived().TransformExpr(E->getArg(1));
if (Second.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
}
if (!getDerived().AlwaysRebuild() &&
@@ -5005,19 +5010,19 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
E->getOperatorLoc(),
- move(Callee),
- move(First),
- move(Second));
+ Callee.get(),
+ First.get(),
+ Second.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
return getDerived().TransformCallExpr(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
TypeSourceInfo *OldT;
TypeSourceInfo *NewT;
@@ -5030,13 +5035,13 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
OldT = E->getTypeInfoAsWritten();
NewT = getDerived().TransformType(OldT);
if (!NewT)
- return SemaRef.ExprError();
+ return ExprError();
}
- OwningExprResult SubExpr
+ ExprResult SubExpr
= getDerived().TransformExpr(E->getSubExprAsWritten());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
OldT == NewT &&
@@ -5056,37 +5061,37 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
NewT,
FakeRAngleLoc,
FakeRAngleLoc,
- move(SubExpr),
+ SubExpr.get(),
FakeRParenLoc);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
return getDerived().TransformCXXNamedCastExpr(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
return getDerived().TransformCXXNamedCastExpr(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
CXXReinterpretCastExpr *E) {
return getDerived().TransformCXXNamedCastExpr(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
return getDerived().TransformCXXNamedCastExpr(E);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
CXXFunctionalCastExpr *E) {
TypeSourceInfo *OldT;
@@ -5097,13 +5102,13 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
OldT = E->getTypeInfoAsWritten();
NewT = getDerived().TransformType(OldT);
if (!NewT)
- return SemaRef.ExprError();
+ return ExprError();
}
- OwningExprResult SubExpr
+ ExprResult SubExpr
= getDerived().TransformExpr(E->getSubExprAsWritten());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
OldT == NewT &&
@@ -5115,18 +5120,18 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
/*FIXME:*/SourceRange(E->getTypeBeginLoc()),
NewT,
/*FIXME:*/E->getSubExpr()->getLocStart(),
- move(SubExpr),
+ SubExpr.get(),
E->getRParenLoc());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
if (E->isTypeOperand()) {
TypeSourceInfo *TInfo
= getDerived().TransformType(E->getTypeOperandSourceInfo());
if (!TInfo)
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
TInfo == E->getTypeOperandSourceInfo())
@@ -5142,11 +5147,11 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
// after we perform semantic analysis, so the expression is potentially
// potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::PotentiallyPotentiallyEvaluated);
+ Sema::PotentiallyPotentiallyEvaluated);
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
+ ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getExprOperand())
@@ -5154,31 +5159,31 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
return getDerived().RebuildCXXTypeidExpr(E->getType(),
E->getLocStart(),
- move(SubExpr),
+ SubExpr.get(),
E->getLocEnd());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
CXXNullPtrLiteralExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
QualType T = getDerived().TransformType(E->getType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
T == E->getType())
@@ -5188,27 +5193,27 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getSubExpr())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
+ return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
ParmVarDecl *Param
= cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
E->getParam()));
if (!Param)
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
Param == E->getParam())
@@ -5218,13 +5223,13 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
QualType T = getDerived().TransformType(E->getType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
T == E->getType())
@@ -5237,40 +5242,40 @@ TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
// Transform the type that we're allocating
TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
QualType AllocType = getDerived().TransformType(E->getAllocatedType());
if (AllocType.isNull())
- return SemaRef.ExprError();
+ return ExprError();
// Transform the size of the array we're allocating (if any).
- OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
+ ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
if (ArraySize.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// Transform the placement arguments (if any).
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+ ASTOwningVector<Expr*> PlacementArgs(SemaRef);
for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
- OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
+ ExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
if (Arg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
PlacementArgs.push_back(Arg.take());
}
// transform the constructor arguments (if any).
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
+ ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
if (getDerived().DropCallArgument(E->getConstructorArg(I)))
break;
- OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
+ ExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
if (Arg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
ConstructorArgs.push_back(Arg.take());
@@ -5283,7 +5288,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
getDerived().TransformDecl(E->getLocStart(),
E->getConstructor()));
if (!Constructor)
- return SemaRef.ExprError();
+ return ExprError();
}
FunctionDecl *OperatorNew = 0;
@@ -5292,7 +5297,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
getDerived().TransformDecl(E->getLocStart(),
E->getOperatorNew()));
if (!OperatorNew)
- return SemaRef.ExprError();
+ return ExprError();
}
FunctionDecl *OperatorDelete = 0;
@@ -5301,7 +5306,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
getDerived().TransformDecl(E->getLocStart(),
E->getOperatorDelete()));
if (!OperatorDelete)
- return SemaRef.ExprError();
+ return ExprError();
}
if (!getDerived().AlwaysRebuild() &&
@@ -5334,10 +5339,10 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
} else if (const ConstantArrayType *ConsArrayT
= dyn_cast<ConstantArrayType>(ArrayT)) {
ArraySize
- = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
- ConsArrayT->getSize(),
- SemaRef.Context.getSizeType(),
- /*FIXME:*/E->getLocStart()));
+ = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
+ ConsArrayT->getSize(),
+ SemaRef.Context.getSizeType(),
+ /*FIXME:*/E->getLocStart()));
AllocType = ConsArrayT->getElementType();
} else if (const DependentSizedArrayType *DepArrayT
= dyn_cast<DependentSizedArrayType>(ArrayT)) {
@@ -5356,18 +5361,18 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
AllocType,
/*FIXME:*/E->getLocStart(),
/*FIXME:*/SourceRange(),
- move(ArraySize),
+ ArraySize.get(),
/*FIXME:*/E->getLocStart(),
move_arg(ConstructorArgs),
E->getLocEnd());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
- OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
+ ExprResult Operand = getDerived().TransformExpr(E->getArgument());
if (Operand.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// Transform the delete operator, if known.
FunctionDecl *OperatorDelete = 0;
@@ -5376,7 +5381,7 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
getDerived().TransformDecl(E->getLocStart(),
E->getOperatorDelete()));
if (!OperatorDelete)
- return SemaRef.ExprError();
+ return ExprError();
}
if (!getDerived().AlwaysRebuild() &&
@@ -5392,41 +5397,41 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
E->isGlobalDelete(),
E->isArrayForm(),
- move(Operand));
+ Operand.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
CXXPseudoDestructorExpr *E) {
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- Sema::TypeTy *ObjectTypePtr = 0;
+ ParsedType ObjectTypePtr;
bool MayBePseudoDestructor = false;
- Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
+ Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
E->getOperatorLoc(),
E->isArrow()? tok::arrow : tok::period,
ObjectTypePtr,
MayBePseudoDestructor);
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+ QualType ObjectType = ObjectTypePtr.get();
NestedNameSpecifier *Qualifier
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange(),
ObjectType);
if (E->getQualifier() && !Qualifier)
- return SemaRef.ExprError();
+ return ExprError();
PseudoDestructorTypeStorage Destroyed;
if (E->getDestroyedTypeInfo()) {
TypeSourceInfo *DestroyedTypeInfo
= getDerived().TransformType(E->getDestroyedTypeInfo(), ObjectType);
if (!DestroyedTypeInfo)
- return SemaRef.ExprError();
+ return ExprError();
Destroyed = DestroyedTypeInfo;
} else if (ObjectType->isDependentType()) {
// We aren't likely to be able to resolve the identifier down to a type
@@ -5441,14 +5446,14 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
SS.setRange(E->getQualifierRange());
}
- Sema::TypeTy *T = SemaRef.getDestructorName(E->getTildeLoc(),
+ ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
*E->getDestroyedTypeIdentifier(),
E->getDestroyedTypeLoc(),
/*Scope=*/0,
SS, ObjectTypePtr,
false);
if (!T)
- return SemaRef.ExprError();
+ return ExprError();
Destroyed
= SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
@@ -5460,10 +5465,10 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo(),
ObjectType);
if (!ScopeTypeInfo)
- return SemaRef.ExprError();
+ return ExprError();
}
- return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
+ return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
E->getOperatorLoc(),
E->isArrow(),
Qualifier,
@@ -5475,7 +5480,7 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformUnresolvedLookupExpr(
UnresolvedLookupExpr *Old) {
TemporaryBase Rebase(*this, Old->getNameLoc(), DeclarationName());
@@ -5495,7 +5500,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
if (isa<UsingShadowDecl>(*I))
continue;
else
- return SemaRef.ExprError();
+ return ExprError();
}
// Expand using declarations.
@@ -5521,7 +5526,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
Old->getQualifierRange());
if (!Qualifier)
- return SemaRef.ExprError();
+ return ExprError();
SS.setScopeRep(Qualifier);
SS.setRange(Old->getQualifierRange());
@@ -5533,7 +5538,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
Old->getNameLoc(),
Old->getNamingClass()));
if (!NamingClass)
- return SemaRef.ExprError();
+ return ExprError();
R.setNamingClass(NamingClass);
}
@@ -5548,7 +5553,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I], Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
@@ -5557,13 +5562,13 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
QualType T = getDerived().TransformType(E->getQueriedType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
T == E->getQueriedType())
@@ -5581,29 +5586,31 @@ TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
- DependentScopeDeclRefExpr *E) {
+ DependentScopeDeclRefExpr *E) {
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange());
if (!NNS)
- return SemaRef.ExprError();
+ return ExprError();
- DeclarationName Name
- = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
- if (!Name)
- return SemaRef.ExprError();
+ DeclarationNameInfo NameInfo
+ = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
+ if (!NameInfo.getName())
+ return ExprError();
if (!E->hasExplicitTemplateArgs()) {
if (!getDerived().AlwaysRebuild() &&
NNS == E->getQualifier() &&
- Name == E->getDeclName())
+ // Note: it is sufficient to compare the Name component of NameInfo:
+ // if name has not changed, DNLoc has not changed either.
+ NameInfo.getName() == E->getDeclName())
return SemaRef.Owned(E->Retain());
return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
E->getQualifierRange(),
- Name, E->getLocation(),
+ NameInfo,
/*TemplateArgs*/ 0);
}
@@ -5611,18 +5618,18 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
E->getQualifierRange(),
- Name, E->getLocation(),
+ NameInfo,
&TransArgs);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
// CXXConstructExprs are always implicit, so when we have a
// 1-argument construction we just transform that argument.
@@ -5634,17 +5641,17 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
QualType T = getDerived().TransformType(E->getType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
CXXConstructorDecl *Constructor
= cast_or_null<CXXConstructorDecl>(
getDerived().TransformDecl(E->getLocStart(),
E->getConstructor()));
if (!Constructor)
- return SemaRef.ExprError();
+ return ExprError();
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
ArgEnd = E->arg_end();
Arg != ArgEnd; ++Arg) {
@@ -5653,12 +5660,12 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
break;
}
- OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+ ExprResult TransArg = getDerived().TransformExpr(*Arg);
if (TransArg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
- Args.push_back(TransArg.takeAs<Expr>());
+ Args.push_back(TransArg.get());
}
if (!getDerived().AlwaysRebuild() &&
@@ -5673,7 +5680,9 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
Constructor, E->isElidable(),
- move_arg(Args));
+ move_arg(Args),
+ E->requiresZeroInitialization(),
+ E->getConstructionKind());
}
/// \brief Transform a C++ temporary-binding expression.
@@ -5681,51 +5690,41 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
/// transform the subexpression and return that.
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
return getDerived().TransformExpr(E->getSubExpr());
}
-/// \brief Transform a C++ reference-binding expression.
-///
-/// Since CXXBindReferenceExpr nodes are implicitly generated, we just
-/// transform the subexpression and return that.
-template<typename Derived>
-Sema::OwningExprResult
-TreeTransform<Derived>::TransformCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
- return getDerived().TransformExpr(E->getSubExpr());
-}
-
/// \brief Transform a C++ expression that contains temporaries that should
/// be destroyed after the expression is evaluated.
///
/// Since CXXExprWithTemporaries nodes are implicitly generated, we
/// just transform the subexpression and return that.
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXExprWithTemporaries(
CXXExprWithTemporaries *E) {
return getDerived().TransformExpr(E->getSubExpr());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
CXXTemporaryObjectExpr *E) {
TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
QualType T = getDerived().TransformType(E->getType());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
CXXConstructorDecl *Constructor
= cast_or_null<CXXConstructorDecl>(
getDerived().TransformDecl(E->getLocStart(),
E->getConstructor()));
if (!Constructor)
- return SemaRef.ExprError();
+ return ExprError();
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
Args.reserve(E->getNumArgs());
for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
ArgEnd = E->arg_end();
@@ -5735,9 +5734,9 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
break;
}
- OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+ ExprResult TransArg = getDerived().TransformExpr(*Arg);
if (TransArg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
Args.push_back((Expr *)TransArg.release());
@@ -5768,28 +5767,28 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
CXXUnresolvedConstructExpr *E) {
TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
QualType T = getDerived().TransformType(E->getTypeAsWritten());
if (T.isNull())
- return SemaRef.ExprError();
+ return ExprError();
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
ArgEnd = E->arg_end();
Arg != ArgEnd; ++Arg) {
- OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+ ExprResult TransArg = getDerived().TransformExpr(*Arg);
if (TransArg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
FakeCommaLocs.push_back(
SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
- Args.push_back(TransArg.takeAs<Expr>());
+ Args.push_back(TransArg.get());
}
if (!getDerived().AlwaysRebuild() &&
@@ -5807,11 +5806,11 @@ TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
- CXXDependentScopeMemberExpr *E) {
+ CXXDependentScopeMemberExpr *E) {
// Transform the base of the expression.
- OwningExprResult Base(SemaRef, (Expr*) 0);
+ ExprResult Base((Expr*) 0);
Expr *OldBase;
QualType BaseType;
QualType ObjectType;
@@ -5819,20 +5818,20 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
OldBase = E->getBase();
Base = getDerived().TransformExpr(OldBase);
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// Start the member reference and compute the object's type.
- Sema::TypeTy *ObjectTy = 0;
+ ParsedType ObjectTy;
bool MayBePseudoDestructor = false;
- Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
+ Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
E->getOperatorLoc(),
E->isArrow()? tok::arrow : tok::period,
ObjectTy,
MayBePseudoDestructor);
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- ObjectType = QualType::getFromOpaquePtr(ObjectTy);
+ ObjectType = ObjectTy.get();
BaseType = ((Expr*) Base.get())->getType();
} else {
OldBase = 0;
@@ -5854,14 +5853,14 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
ObjectType,
FirstQualifierInScope);
if (!Qualifier)
- return SemaRef.ExprError();
+ return ExprError();
}
- DeclarationName Name
- = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
- ObjectType);
- if (!Name)
- return SemaRef.ExprError();
+ DeclarationNameInfo NameInfo
+ = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo(),
+ ObjectType);
+ if (!NameInfo.getName())
+ return ExprError();
if (!E->hasExplicitTemplateArgs()) {
// This is a reference to a member without an explicitly-specified
@@ -5870,19 +5869,18 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
Base.get() == OldBase &&
BaseType == E->getBaseType() &&
Qualifier == E->getQualifier() &&
- Name == E->getMember() &&
+ NameInfo.getName() == E->getMember() &&
FirstQualifierInScope == E->getFirstQualifierFoundInScope())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+ return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
BaseType,
E->isArrow(),
E->getOperatorLoc(),
Qualifier,
E->getQualifierRange(),
FirstQualifierInScope,
- Name,
- E->getMemberLoc(),
+ NameInfo,
/*TemplateArgs*/ 0);
}
@@ -5890,32 +5888,31 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
- return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+ return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
BaseType,
E->isArrow(),
E->getOperatorLoc(),
Qualifier,
E->getQualifierRange(),
FirstQualifierInScope,
- Name,
- E->getMemberLoc(),
+ NameInfo,
&TransArgs);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
// Transform the base of the expression.
- OwningExprResult Base(SemaRef, (Expr*) 0);
+ ExprResult Base((Expr*) 0);
QualType BaseType;
if (!Old->isImplicitAccess()) {
Base = getDerived().TransformExpr(Old->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
BaseType = ((Expr*) Base.get())->getType();
} else {
BaseType = getDerived().TransformType(Old->getBaseType());
@@ -5927,10 +5924,10 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
= getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
Old->getQualifierRange());
if (Qualifier == 0)
- return SemaRef.ExprError();
+ return ExprError();
}
- LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
+ LookupResult R(SemaRef, Old->getMemberNameInfo(),
Sema::LookupOrdinaryName);
// Transform all the decls.
@@ -5945,7 +5942,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
if (isa<UsingShadowDecl>(*I))
continue;
else
- return SemaRef.ExprError();
+ return ExprError();
}
// Expand using declarations.
@@ -5969,7 +5966,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
Old->getMemberLoc(),
Old->getNamingClass()));
if (!NamingClass)
- return SemaRef.ExprError();
+ return ExprError();
R.setNamingClass(NamingClass);
}
@@ -5982,7 +5979,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I],
Loc))
- return SemaRef.ExprError();
+ return ExprError();
TransArgs.addArgument(Loc);
}
}
@@ -5993,7 +5990,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
// nested-name-qualifier (and therefore could do the lookup).
NamedDecl *FirstQualifierInScope = 0;
- return getDerived().RebuildUnresolvedMemberExpr(move(Base),
+ return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
BaseType,
Old->getOperatorLoc(),
Old->isArrow(),
@@ -6006,18 +6003,18 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
TypeSourceInfo *EncodedTypeInfo
= getDerived().TransformType(E->getEncodedTypeSourceInfo());
if (!EncodedTypeInfo)
- return SemaRef.ExprError();
+ return ExprError();
if (!getDerived().AlwaysRebuild() &&
EncodedTypeInfo == E->getEncodedTypeSourceInfo())
@@ -6029,18 +6026,18 @@ TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
// Transform arguments.
bool ArgChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ ASTOwningVector<Expr*> Args(SemaRef);
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
- OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+ ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
if (Arg.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
- Args.push_back(Arg.takeAs<Expr>());
+ Args.push_back(Arg.get());
}
if (E->getReceiverKind() == ObjCMessageExpr::Class) {
@@ -6048,7 +6045,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
TypeSourceInfo *ReceiverTypeInfo
= getDerived().TransformType(E->getClassReceiverTypeInfo());
if (!ReceiverTypeInfo)
- return SemaRef.ExprError();
+ return ExprError();
// If nothing changed, just retain the existing message send.
if (!getDerived().AlwaysRebuild() &&
@@ -6067,10 +6064,10 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
// Instance message: transform the receiver
assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
"Only class and instance messages may be instantiated");
- OwningExprResult Receiver
+ ExprResult Receiver
= getDerived().TransformExpr(E->getInstanceReceiver());
if (Receiver.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// If nothing changed, just retain the existing message send.
if (!getDerived().AlwaysRebuild() &&
@@ -6078,7 +6075,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
return SemaRef.Owned(E->Retain());
// Build a new instance message send.
- return getDerived().RebuildObjCMessageExpr(move(Receiver),
+ return getDerived().RebuildObjCMessageExpr(Receiver.get(),
E->getSelector(),
E->getMethodDecl(),
E->getLeftLoc(),
@@ -6087,24 +6084,24 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
// Transform the base expression.
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// We don't need to transform the ivar; it will never change.
@@ -6113,18 +6110,18 @@ TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Base.get() == E->getBase())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildObjCIvarRefExpr(move(Base), E->getDecl(),
+ return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
E->getLocation(),
E->isArrow(), E->isFreeIvar());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
// Transform the base expression.
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// We don't need to transform the property; it will never change.
@@ -6133,12 +6130,12 @@ TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
Base.get() == E->getBase())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
+ return getDerived().RebuildObjCPropertyRefExpr(Base.get(), E->getProperty(),
E->getLocation());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
ObjCImplicitSetterGetterRefExpr *E) {
// If this implicit setter/getter refers to class methods, it cannot have any
@@ -6147,9 +6144,9 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
return SemaRef.Owned(E->Retain());
// Transform the base expression.
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// We don't need to transform the getters/setters; they will never change.
@@ -6163,46 +6160,46 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
E->getType(),
E->getSetterMethod(),
E->getLocation(),
- move(Base));
+ Base.get());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
// Can never occur in a dependent context.
return SemaRef.Owned(E->Retain());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
// Transform the base expression.
- OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ ExprResult Base = getDerived().TransformExpr(E->getBase());
if (Base.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// If nothing changed, just retain the existing expression.
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildObjCIsaExpr(move(Base), E->getIsaMemberLoc(),
+ return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
E->isArrow());
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
bool ArgumentChanged = false;
- ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+ ASTOwningVector<Expr*> SubExprs(SemaRef);
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
- OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
+ ExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
if (SubExpr.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
- SubExprs.push_back(SubExpr.takeAs<Expr>());
+ SubExprs.push_back(SubExpr.get());
}
if (!getDerived().AlwaysRebuild() &&
@@ -6215,7 +6212,7 @@ TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
SourceLocation CaretLoc(E->getExprLoc());
@@ -6246,9 +6243,9 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
}
// Transform the body
- OwningStmtResult Body = getDerived().TransformStmt(E->getBody());
+ StmtResult Body = getDerived().TransformStmt(E->getBody());
if (Body.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
// Set the parameters on the block decl.
if (!Params.empty())
CurBlock->TheDecl->setParams(Params.data(), Params.size());
@@ -6258,14 +6255,15 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
ParamTypes.data(),
ParamTypes.size(),
BD->isVariadic(),
- 0);
+ 0,
+ BExprFunctionType->getExtInfo());
CurBlock->FunctionType = FunctionType;
- return SemaRef.ActOnBlockStmtExpr(CaretLoc, move(Body), /*Scope=*/0);
+ return SemaRef.ActOnBlockStmtExpr(CaretLoc, Body.get(), /*Scope=*/0);
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
NestedNameSpecifier *Qualifier = 0;
@@ -6273,8 +6271,8 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
= cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
E->getDecl()));
if (!ND)
- return SemaRef.ExprError();
-
+ return ExprError();
+
if (!getDerived().AlwaysRebuild() &&
ND == E->getDecl()) {
// Mark it referenced in the new context regardless.
@@ -6284,8 +6282,9 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
return SemaRef.Owned(E->Retain());
}
+ DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation());
return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
- ND, E->getLocation(), 0);
+ ND, NameInfo, 0);
}
//===----------------------------------------------------------------------===//
@@ -6350,7 +6349,8 @@ TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
break;
}
- IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
+ IntegerLiteral ArraySize(SemaRef.Context, *Size, SizeType,
+ /*FIXME*/BracketsRange.getBegin());
return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
IndexTypeQuals, BracketsRange,
getDerived().getBaseEntity());
@@ -6381,11 +6381,11 @@ template<typename Derived>
QualType
TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange) {
return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
- SizeExpr.takeAs<Expr>(),
+ SizeExpr,
IndexTypeQuals, BracketsRange);
}
@@ -6393,11 +6393,11 @@ template<typename Derived>
QualType
TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange) {
return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
- SizeExpr.takeAs<Expr>(),
+ SizeExpr,
IndexTypeQuals, BracketsRange);
}
@@ -6416,18 +6416,17 @@ QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
NumElements, true);
IntegerLiteral *VectorSize
- = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
- AttributeLoc);
- return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
- AttributeLoc);
+ = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
+ AttributeLoc);
+ return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
}
template<typename Derived>
QualType
TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
- ExprArg SizeExpr,
+ Expr *SizeExpr,
SourceLocation AttributeLoc) {
- return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
+ return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
}
template<typename Derived>
@@ -6435,11 +6434,13 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
QualType *ParamTypes,
unsigned NumParamTypes,
bool Variadic,
- unsigned Quals) {
+ unsigned Quals,
+ const FunctionType::ExtInfo &Info) {
return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Quals,
getDerived().getBaseLocation(),
- getDerived().getBaseEntity());
+ getDerived().getBaseEntity(),
+ Info);
}
template<typename Derived>
@@ -6473,8 +6474,8 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
}
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
- return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E) {
+ return SemaRef.BuildTypeofExprType(E);
}
template<typename Derived>
@@ -6483,8 +6484,8 @@ QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
}
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
- return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E) {
+ return SemaRef.BuildDecltypeType(E);
}
template<typename Derived>
@@ -6563,7 +6564,7 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
/*FIXME:*/getDerived().getBaseLocation(),
SS,
Name,
- ObjectType.getAsOpaquePtr(),
+ ParsedType::make(ObjectType),
/*EnteringContext=*/false,
Template);
return Template.template getAsVal<TemplateName>();
@@ -6586,56 +6587,52 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
/*FIXME:*/getDerived().getBaseLocation(),
SS,
Name,
- ObjectType.getAsOpaquePtr(),
+ ParsedType::make(ObjectType),
/*EnteringContext=*/false,
Template);
return Template.template getAsVal<TemplateName>();
}
template<typename Derived>
-Sema::OwningExprResult
+ExprResult
TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
SourceLocation OpLoc,
- ExprArg Callee,
- ExprArg First,
- ExprArg Second) {
- Expr *FirstExpr = (Expr *)First.get();
- Expr *SecondExpr = (Expr *)Second.get();
- Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
- bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
+ Expr *OrigCallee,
+ Expr *First,
+ Expr *Second) {
+ Expr *Callee = OrigCallee->IgnoreParenCasts();
+ bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
// Determine whether this should be a builtin operation.
if (Op == OO_Subscript) {
- if (!FirstExpr->getType()->isOverloadableType() &&
- !SecondExpr->getType()->isOverloadableType())
- return getSema().CreateBuiltinArraySubscriptExpr(move(First),
- CalleeExpr->getLocStart(),
- move(Second), OpLoc);
+ if (!First->getType()->isOverloadableType() &&
+ !Second->getType()->isOverloadableType())
+ return getSema().CreateBuiltinArraySubscriptExpr(First,
+ Callee->getLocStart(),
+ Second, OpLoc);
} else if (Op == OO_Arrow) {
// -> is never a builtin operation.
- return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
- } else if (SecondExpr == 0 || isPostIncDec) {
- if (!FirstExpr->getType()->isOverloadableType()) {
+ return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
+ } else if (Second == 0 || isPostIncDec) {
+ if (!First->getType()->isOverloadableType()) {
// The argument is not of overloadable type, so try to create a
// built-in unary operation.
- UnaryOperator::Opcode Opc
+ UnaryOperatorKind Opc
= UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
- return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
+ return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
}
} else {
- if (!FirstExpr->getType()->isOverloadableType() &&
- !SecondExpr->getType()->isOverloadableType()) {
+ if (!First->getType()->isOverloadableType() &&
+ !Second->getType()->isOverloadableType()) {
// Neither of the arguments is an overloadable type, so try to
// create a built-in binary operation.
- BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
- OwningExprResult Result
- = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
+ BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+ ExprResult Result
+ = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
if (Result.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- First.release();
- Second.release();
return move(Result);
}
}
@@ -6644,49 +6641,46 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
// used during overload resolution.
UnresolvedSet<16> Functions;
- if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
+ if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
assert(ULE->requiresADL());
// FIXME: Do we have to check
// IsAcceptableNonMemberOperatorCandidate for each of these?
Functions.append(ULE->decls_begin(), ULE->decls_end());
} else {
- Functions.addDecl(cast<DeclRefExpr>(CalleeExpr)->getDecl());
+ Functions.addDecl(cast<DeclRefExpr>(Callee)->getDecl());
}
// Add any functions found via argument-dependent lookup.
- Expr *Args[2] = { FirstExpr, SecondExpr };
- unsigned NumArgs = 1 + (SecondExpr != 0);
+ Expr *Args[2] = { First, Second };
+ unsigned NumArgs = 1 + (Second != 0);
// Create the overloaded operator invocation for unary operators.
if (NumArgs == 1 || isPostIncDec) {
- UnaryOperator::Opcode Opc
+ UnaryOperatorKind Opc
= UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
- return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
+ return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First);
}
if (Op == OO_Subscript)
- return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
+ return SemaRef.CreateOverloadedArraySubscriptExpr(Callee->getLocStart(),
OpLoc,
- move(First),
- move(Second));
+ First,
+ Second);
// Create the overloaded operator invocation for binary operators.
- BinaryOperator::Opcode Opc =
- BinaryOperator::getOverloadedOpcode(Op);
- OwningExprResult Result
+ BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+ ExprResult Result
= SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
if (Result.isInvalid())
- return SemaRef.ExprError();
+ return ExprError();
- First.release();
- Second.release();
return move(Result);
}
template<typename Derived>
-Sema::OwningExprResult
-TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
+ExprResult
+TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
SourceLocation OperatorLoc,
bool isArrow,
NestedNameSpecifier *Qualifier,
@@ -6701,32 +6695,32 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
SS.setScopeRep(Qualifier);
}
- Expr *BaseE = (Expr *)Base.get();
- QualType BaseType = BaseE->getType();
- if (BaseE->isTypeDependent() || Destroyed.getIdentifier() ||
+ QualType BaseType = Base->getType();
+ if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
(!isArrow && !BaseType->getAs<RecordType>()) ||
(isArrow && BaseType->getAs<PointerType>() &&
!BaseType->getAs<PointerType>()->getPointeeType()
->template getAs<RecordType>())){
// This pseudo-destructor expression is still a pseudo-destructor.
- return SemaRef.BuildPseudoDestructorExpr(move(Base), OperatorLoc,
+ return SemaRef.BuildPseudoDestructorExpr(Base, OperatorLoc,
isArrow? tok::arrow : tok::period,
SS, ScopeType, CCLoc, TildeLoc,
Destroyed,
/*FIXME?*/true);
}
-
+
TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
- DeclarationName Name
- = SemaRef.Context.DeclarationNames.getCXXDestructorName(
- SemaRef.Context.getCanonicalType(DestroyedType->getType()));
-
+ DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
+ SemaRef.Context.getCanonicalType(DestroyedType->getType())));
+ DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
+ NameInfo.setNamedTypeInfo(DestroyedType);
+
// FIXME: the ScopeType should be tacked onto SS.
-
- return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+
+ return getSema().BuildMemberReferenceExpr(Base, BaseType,
OperatorLoc, isArrow,
SS, /*FIXME: FirstQualifier*/ 0,
- Name, Destroyed.getLocation(),
+ NameInfo,
/*TemplateArgs*/ 0);
}