forked from OSchip/llvm-project
Add Sema::isStdInitializerList, which will be necessary for the upcoming operations.
llvm-svn: 148348
This commit is contained in:
parent
d51a710bde
commit
2bfa104b40
|
@ -488,6 +488,10 @@ public:
|
|||
/// standard library.
|
||||
LazyDeclPtr StdBadAlloc;
|
||||
|
||||
/// \brief The C++ "std::initializer_list" template, which is defined in
|
||||
/// <initializer_list>.
|
||||
ClassTemplateDecl *StdInitializerList;
|
||||
|
||||
/// \brief The C++ "type_info" declaration, which is defined in <typeinfo>.
|
||||
RecordDecl *CXXTypeInfoDecl;
|
||||
|
||||
|
@ -2721,6 +2725,10 @@ public:
|
|||
|
||||
CXXRecordDecl *getStdBadAlloc() const;
|
||||
|
||||
/// \brief Tests whether Ty is an instance of std::initializer_list and, if
|
||||
/// it is and Element is not NULL, assigns the element type to Element.
|
||||
bool isStdInitializerList(QualType Ty, QualType *Element);
|
||||
|
||||
Decl *ActOnUsingDirective(Scope *CurScope,
|
||||
SourceLocation UsingLoc,
|
||||
SourceLocation NamespcLoc,
|
||||
|
|
|
@ -89,7 +89,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
|
|||
CurContext(0), OriginalLexicalContext(0),
|
||||
PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
||||
ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
|
||||
IdResolver(pp), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
||||
IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
||||
GlobalNewDeleteDeclared(false),
|
||||
ObjCShouldCallSuperDealloc(false),
|
||||
ObjCShouldCallSuperFinalize(false),
|
||||
|
|
|
@ -5767,6 +5767,59 @@ NamespaceDecl *Sema::getOrCreateStdNamespace() {
|
|||
return getStdNamespace();
|
||||
}
|
||||
|
||||
bool Sema::isStdInitializerList(QualType Ty, QualType *Element) {
|
||||
assert(getLangOptions().CPlusPlus &&
|
||||
"Looking for std::initializer_list outside of C++.");
|
||||
|
||||
// We're looking for implicit instantiations of
|
||||
// template <typename E> class std::initializer_list.
|
||||
|
||||
if (!StdNamespace) // If we haven't seen namespace std yet, this can't be it.
|
||||
return false;
|
||||
|
||||
const RecordType *RT = Ty->getAs<RecordType>();
|
||||
if (!RT)
|
||||
return false;
|
||||
|
||||
ClassTemplateSpecializationDecl *Specialization =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
|
||||
if (!Specialization)
|
||||
return false;
|
||||
|
||||
if (Specialization->getSpecializationKind() != TSK_ImplicitInstantiation)
|
||||
return false;
|
||||
|
||||
ClassTemplateDecl *Template = Specialization->getSpecializedTemplate();
|
||||
|
||||
if (!StdInitializerList) {
|
||||
// Haven't recognized std::initializer_list yet, maybe this is it.
|
||||
CXXRecordDecl *TemplateClass = Template->getTemplatedDecl();
|
||||
if (TemplateClass->getIdentifier() !=
|
||||
&PP.getIdentifierTable().get("initializer_list") ||
|
||||
!TemplateClass->getDeclContext()->Equals(getStdNamespace()))
|
||||
return false;
|
||||
// This is a template called std::initializer_list, but is it the right
|
||||
// template?
|
||||
TemplateParameterList *Params = Template->getTemplateParameters();
|
||||
if (Params->size() != 1)
|
||||
return false;
|
||||
if (!isa<TemplateTypeParmDecl>(Params->getParam(0)))
|
||||
return false;
|
||||
|
||||
// It's the right template.
|
||||
StdInitializerList = Template;
|
||||
}
|
||||
|
||||
if (Template != StdInitializerList)
|
||||
return false;
|
||||
|
||||
// This is an instance of std::initializer_list. Find the argument type.
|
||||
if (Element) {
|
||||
*Element = Specialization->getTemplateArgs()[0].getAsType();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Determine whether a using statement is in a context where it will be
|
||||
/// apply in all contexts.
|
||||
static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
|
||||
|
|
Loading…
Reference in New Issue