summaryrefslogtreecommitdiffstats
path: root/lib/Sema
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-10-15 07:44:25 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-10-15 07:44:25 +0000
commit67e5495076feb6c1338273ace96b58da95cdaf61 (patch)
treebadd8f913c2a7db8d5fbe7d83c862e35e403fd41 /lib/Sema
parent9092c3e0fa01f3139b016d05d267a89e3b07747a (diff)
downloadFreeBSD-src-67e5495076feb6c1338273ace96b58da95cdaf61.zip
FreeBSD-src-67e5495076feb6c1338273ace96b58da95cdaf61.tar.gz
Update clang to 84175.
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp17
-rw-r--r--lib/Sema/SemaTemplate.cpp246
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp12
-rw-r--r--lib/Sema/SemaType.cpp3
6 files changed, 205 insertions, 82 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index acb2a67..419c8a1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1836,7 +1836,7 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
if (RD->isAbstract())
AbstractClassUsageDiagnoser(*this, RD);
- if (!RD->isDependentType())
+ if (!RD->isDependentType() && !RD->isInvalidDecl())
AddImplicitlyDeclaredMembersToClass(RD);
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d8e49c7..a946500 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2917,15 +2917,18 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
if (BO->getOpcode() == BinaryOperator::PtrMemD ||
BO->getOpcode() == BinaryOperator::PtrMemI) {
const FunctionProtoType *FPT = cast<FunctionProtoType>(BO->getType());
- QualType ReturnTy = FPT->getResultType();
+ QualType ResultTy = FPT->getResultType().getNonReferenceType();
- CXXMemberCallExpr *CE =
- new (Context) CXXMemberCallExpr(Context, BO, Args, NumArgs,
- ReturnTy.getNonReferenceType(),
- RParenLoc);
-
- ExprOwningPtr<CXXMemberCallExpr> TheCall(this, CE);
+ ExprOwningPtr<CXXMemberCallExpr>
+ TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
+ NumArgs, ResultTy,
+ RParenLoc));
+ if (CheckCallReturnType(FPT->getResultType(),
+ BO->getRHS()->getSourceRange().getBegin(),
+ TheCall.get(), 0))
+ return ExprError();
+
if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
RParenLoc))
return ExprError();
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index d56b4e1..ab0bbe0 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -2398,12 +2398,11 @@ static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) {
return TSK_Undeclared;
}
-/// \brief Check whether a specialization or explicit instantiation is
-/// well-formed in the current context.
+/// \brief Check whether a specialization is well-formed in the current
+/// context.
///
-/// This routine determines whether a template specialization or
-/// explicit instantiation can be declared in the current context
-/// (C++ [temp.expl.spec]p2, C++0x [temp.explicit]p2).
+/// This routine determines whether a template specialization can be declared
+/// in the current context (C++ [temp.expl.spec]p2).
///
/// \param S the semantic analysis object for which this check is being
/// performed.
@@ -2421,17 +2420,13 @@ static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) {
/// \param IsPartialSpecialization whether this is a partial specialization of
/// a class template.
///
-/// \param TSK the kind of specialization or implicit instantiation being
-/// performed.
-///
/// \returns true if there was an error that we cannot recover from, false
/// otherwise.
static bool CheckTemplateSpecializationScope(Sema &S,
NamedDecl *Specialized,
NamedDecl *PrevDecl,
SourceLocation Loc,
- bool IsPartialSpecialization,
- TemplateSpecializationKind TSK) {
+ bool IsPartialSpecialization) {
// Keep these "kind" numbers in sync with the %select statements in the
// various diagnostics emitted by this routine.
int EntityKind = 0;
@@ -2449,8 +2444,8 @@ static bool CheckTemplateSpecializationScope(Sema &S,
else if (isa<RecordDecl>(Specialized))
EntityKind = 5;
else {
- S.Diag(Loc, diag::err_template_spec_unknown_kind) << TSK;
- S.Diag(Specialized->getLocation(), diag::note_specialized_entity) << TSK;
+ S.Diag(Loc, diag::err_template_spec_unknown_kind);
+ S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
return true;
}
@@ -2469,13 +2464,13 @@ static bool CheckTemplateSpecializationScope(Sema &S,
// declared.
if (S.CurContext->getLookupContext()->isFunctionOrMethod()) {
S.Diag(Loc, diag::err_template_spec_decl_function_scope)
- << TSK << Specialized;
+ << Specialized;
return true;
}
if (S.CurContext->isRecord() && !IsPartialSpecialization) {
S.Diag(Loc, diag::err_template_spec_decl_class_scope)
- << TSK << Specialized;
+ << Specialized;
return true;
}
@@ -2487,43 +2482,36 @@ static bool CheckTemplateSpecializationScope(Sema &S,
DeclContext *SpecializedContext
= Specialized->getDeclContext()->getEnclosingNamespaceContext();
DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
- if (TSK == TSK_ExplicitSpecialization) {
- if ((!PrevDecl ||
- getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
- 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)) {
- if (isa<TranslationUnitDecl>(SpecializedContext))
- S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
- << EntityKind << Specialized;
- else if (isa<NamespaceDecl>(SpecializedContext))
- S.Diag(Loc, diag::err_template_spec_decl_out_of_scope)
- << EntityKind << Specialized
- << cast<NamedDecl>(SpecializedContext);
-
- S.Diag(Specialized->getLocation(), diag::note_specialized_entity)
- << TSK;
- ComplainedAboutScope = true;
- }
+ if ((!PrevDecl ||
+ getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
+ 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)) {
+ if (isa<TranslationUnitDecl>(SpecializedContext))
+ S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
+ << EntityKind << Specialized;
+ else if (isa<NamespaceDecl>(SpecializedContext))
+ S.Diag(Loc, diag::err_template_spec_decl_out_of_scope)
+ << EntityKind << Specialized
+ << cast<NamedDecl>(SpecializedContext);
+
+ S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
+ ComplainedAboutScope = true;
}
}
// Make sure that this redeclaration (or definition) occurs in an enclosing
- // namespace. We perform this check for explicit specializations and, in
- // C++0x, for explicit instantiations as well (per DR275).
- // FIXME: -Wc++0x should make these warnings.
+ // namespace.
// Note that HandleDeclarator() performs this check for explicit
// specializations of function templates, static data members, and member
// functions, so we skip the check here for those kinds of entities.
// FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
// Should we refactor that check, so that it occurs later?
if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) &&
- ((TSK == TSK_ExplicitSpecialization &&
- !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) ||
- isa<FunctionDecl>(Specialized))) ||
- S.getLangOptions().CPlusPlus0x)) {
+ !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) ||
+ isa<FunctionDecl>(Specialized))) {
if (isa<TranslationUnitDecl>(SpecializedContext))
S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
<< EntityKind << Specialized;
@@ -2532,7 +2520,7 @@ static bool CheckTemplateSpecializationScope(Sema &S,
<< EntityKind << Specialized
<< cast<NamedDecl>(SpecializedContext);
- S.Diag(Specialized->getLocation(), diag::note_specialized_entity) << TSK;
+ S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
}
// FIXME: check for specialization-after-instantiation errors and such.
@@ -2835,8 +2823,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// the current scope.
if (TUK != TUK_Friend &&
CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl,
- TemplateNameLoc, isPartialSpecialization,
- TSK_ExplicitSpecialization))
+ TemplateNameLoc,
+ isPartialSpecialization))
return true;
// The canonical type
@@ -3146,7 +3134,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
if (CheckTemplateSpecializationScope(*this,
Specialization->getPrimaryTemplate(),
Specialization, FD->getLocation(),
- false, TSK_ExplicitSpecialization))
+ false))
return true;
// C++ [temp.expl.spec]p6:
@@ -3273,7 +3261,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
if (CheckTemplateSpecializationScope(*this,
InstantiatedFrom,
Instantiation, Member->getLocation(),
- false, TSK_ExplicitSpecialization))
+ false))
return true;
// Note that this is an explicit instantiation of a member.
@@ -3325,6 +3313,68 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
return false;
}
+/// \brief Check the scope of an explicit instantiation.
+static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
+ SourceLocation InstLoc,
+ bool WasQualifiedName) {
+ DeclContext *ExpectedContext
+ = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
+ DeclContext *CurContext = S.CurContext->getLookupContext();
+
+ // C++0x [temp.explicit]p2:
+ // An explicit instantiation shall appear in an enclosing namespace of its
+ // template.
+ //
+ // 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))
+ S.Diag(InstLoc, diag::err_explicit_instantiation_out_of_scope)
+ << D << NS;
+ else
+ S.Diag(InstLoc, diag::err_explicit_instantiation_must_be_global)
+ << D;
+ S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+ return;
+ }
+
+ // 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
+ // its template is declared or, if that namespace is inline (7.3.1), any
+ // namespace from its enclosing namespace set.
+ if (WasQualifiedName)
+ return;
+
+ if (CurContext->Equals(ExpectedContext))
+ return;
+
+ S.Diag(InstLoc, diag::err_explicit_instantiation_unqualified_wrong_namespace)
+ << D << ExpectedContext;
+ S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
+}
+
+/// \brief Determine whether the given scope specifier has a template-id in it.
+static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
+ if (!SS.isSet())
+ return false;
+
+ // C++0x [temp.explicit]p2:
+ // If the explicit instantiation is for a member function, a member class
+ // or a static data member of a class template specialization, the name of
+ // the class template specialization in the qualified-id for the member
+ // name shall be a simple-template-id.
+ //
+ // C++98 has the same restriction, just worded differently.
+ for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+ NNS; NNS = NNS->getPrefix())
+ if (Type *T = NNS->getAsType())
+ if (isa<TemplateSpecializationType>(T))
+ return true;
+
+ return false;
+}
+
// Explicit instantiation of a class template specialization
// FIXME: Implement extern template semantics
Sema::DeclResult
@@ -3367,6 +3417,10 @@ Sema::ActOnExplicitInstantiation(Scope *S,
Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
}
+ // C++0x [temp.explicit]p2:
+ // There are two forms of explicit instantiation: an explicit instantiation
+ // definition and an explicit instantiation declaration. An explicit
+ // instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
@@ -3404,10 +3458,8 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// namespace of its template. [...]
//
// This is C++ DR 275.
- if (CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl,
- TemplateNameLoc, false,
- TSK))
- return true;
+ CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
+ SS.isSet());
ClassTemplateSpecializationDecl *Specialization = 0;
@@ -3563,7 +3615,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
if (Tag->isInvalidDecl())
return true;
-
+
CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag);
CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
if (!Pattern) {
@@ -3574,25 +3626,29 @@ Sema::ActOnExplicitInstantiation(Scope *S,
}
// C++0x [temp.explicit]p2:
- // [...] An explicit instantiation shall appear in an enclosing
- // namespace of its template. [...]
+ // If the explicit instantiation is for a class or member class, the
+ // elaborated-type-specifier in the declaration shall include a
+ // simple-template-id.
//
- // This is C++ DR 275.
- if (getLangOptions().CPlusPlus0x) {
- // FIXME: In C++98, we would like to turn these errors into warnings,
- // dependent on a -Wc++0x flag.
- DeclContext *PatternContext
- = Pattern->getDeclContext()->getEnclosingNamespaceContext();
- if (!CurContext->Encloses(PatternContext)) {
- Diag(TemplateLoc, diag::err_explicit_instantiation_out_of_scope)
- << Record << cast<NamedDecl>(PatternContext) << SS.getRange();
- Diag(Pattern->getLocation(), diag::note_previous_declaration);
- }
- }
-
+ // C++98 has the same restriction, just worded differently.
+ if (!ScopeSpecifierHasTemplateId(SS))
+ Diag(TemplateLoc, diag::err_explicit_instantiation_without_qualified_id)
+ << Record << SS.getRange();
+
+ // C++0x [temp.explicit]p2:
+ // There are two forms of explicit instantiation: an explicit instantiation
+ // definition and an explicit instantiation declaration. An explicit
+ // instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
+
+ // C++0x [temp.explicit]p2:
+ // [...] An explicit instantiation shall appear in an enclosing
+ // namespace of its template. [...]
+ //
+ // This is C++ DR 275.
+ CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
if (!Record->getDefinition(Context)) {
// If the class has a definition, instantiate it (and all of its
@@ -3647,11 +3703,27 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return true;
}
- // Determine what kind of explicit instantiation we have.
+ // C++0x [temp.explicit]p1:
+ // [...] An explicit instantiation of a function template shall not use the
+ // inline or constexpr specifiers.
+ // Presumably, this also applies to member functions of class templates as
+ // well.
+ if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x)
+ Diag(D.getDeclSpec().getInlineSpecLoc(),
+ diag::err_explicit_instantiation_inline)
+ << CodeModificationHint::CreateRemoval(
+ SourceRange(D.getDeclSpec().getInlineSpecLoc()));
+
+ // FIXME: check for constexpr specifier.
+
+ // C++0x [temp.explicit]p2:
+ // There are two forms of explicit instantiation: an explicit instantiation
+ // definition and an explicit instantiation declaration. An explicit
+ // instantiation declaration begins with the extern keyword. [...]
TemplateSpecializationKind TSK
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
-
+
LookupResult Previous;
LookupParsedName(Previous, S, &D.getCXXScopeSpec(),
Name, LookupOrdinaryName);
@@ -3688,6 +3760,21 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return true;
}
+ // C++0x [temp.explicit]p2:
+ // If the explicit instantiation is for a member function, a member class
+ // or a static data member of a class template specialization, the name of
+ // the class template specialization in the qualified-id for the member
+ // name shall be a simple-template-id.
+ //
+ // C++98 has the same restriction, just worded differently.
+ if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
+ Diag(D.getIdentifierLoc(),
+ diag::err_explicit_instantiation_without_qualified_id)
+ << Prev << D.getCXXScopeSpec().getRange();
+
+ // Check the scope of this explicit instantiation.
+ CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true);
+
// Instantiate static data member.
// FIXME: Check for prior specializations and such.
Prev->setTemplateSpecializationKind(TSK);
@@ -3798,6 +3885,29 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
break;
}
+ // Check the scope of this explicit instantiation.
+ FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
+
+ // C++0x [temp.explicit]p2:
+ // If the explicit instantiation is for a member function, a member class
+ // or a static data member of a class template specialization, the name of
+ // the class template specialization in the qualified-id for the member
+ // name shall be a simple-template-id.
+ //
+ // C++98 has the same restriction, just worded differently.
+ if (D.getKind() != Declarator::DK_TemplateId && !FunTmpl &&
+ D.getCXXScopeSpec().isSet() &&
+ !ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
+ Diag(D.getIdentifierLoc(),
+ diag::err_explicit_instantiation_without_qualified_id)
+ << Specialization << D.getCXXScopeSpec().getRange();
+
+ CheckExplicitInstantiationScope(*this,
+ FunTmpl? (NamedDecl *)FunTmpl
+ : Specialization->getInstantiatedFromMemberFunction(),
+ D.getIdentifierLoc(),
+ D.getCXXScopeSpec().isSet());
+
// FIXME: Create some kind of ExplicitInstantiationDecl here.
return DeclPtrTy();
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 65260c8..24b8370 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -808,9 +808,12 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
0);
-
+ if (Instantiation->isInvalidDecl())
+ Invalid = true;
+
// Add any implicitly-declared members that we might need.
- AddImplicitlyDeclaredMembersToClass(Instantiation);
+ if (!Invalid)
+ AddImplicitlyDeclaredMembersToClass(Instantiation);
// Exit the scope of this instantiation.
CurContext = PreviousContext;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 33fa288..060cc55 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -246,8 +246,10 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
D->getTypeSpecStartLoc(),
D->getAccess(),
0);
- if (!Field)
+ if (!Field) {
+ cast<Decl>(Owner)->setInvalidDecl();
return 0;
+ }
if (Invalid)
Field->setInvalidDecl();
@@ -1189,14 +1191,14 @@ void Sema::InstantiateStaticDataMemberDefinition(
}
// Never instantiate an explicit specialization.
- if (Def->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return;
// C++0x [temp.explicit]p9:
// Except for inline functions, other explicit instantiation declarations
// have the effect of suppressing the implicit instantiation of the entity
// to which they refer.
- if (Def->getTemplateSpecializationKind()
+ if (Var->getTemplateSpecializationKind()
== TSK_ExplicitInstantiationDeclaration)
return;
@@ -1216,12 +1218,14 @@ void Sema::InstantiateStaticDataMemberDefinition(
DeclContext *PreviousContext = CurContext;
CurContext = Var->getDeclContext();
+ VarDecl *OldVar = Var;
Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(),
getTemplateInstantiationArgs(Var)));
-
CurContext = PreviousContext;
if (Var) {
+ Var->setPreviousDeclaration(OldVar);
+ Var->setTemplateSpecializationKind(OldVar->getTemplateSpecializationKind());
DeclGroupRef DG(Var);
Consumer.HandleTopLevelDecl(DG);
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 3cdf615..9603ca8 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1333,6 +1333,9 @@ Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
assert(!CurrTL.isNull());
+
+ // Don't bother recording source locations for qualifiers.
+ CurrTL = CurrTL.getUnqualifiedLoc();
DeclaratorChunk &DeclType = D.getTypeObject(i);
switch (DeclType.Kind) {
OpenPOWER on IntegriCloud