summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp113
-rw-r--r--lib/AST/Decl.cpp205
-rw-r--r--lib/AST/DeclBase.cpp15
-rw-r--r--lib/AST/DeclCXX.cpp46
-rw-r--r--lib/AST/DeclPrinter.cpp15
-rw-r--r--lib/AST/DeclTemplate.cpp7
-rw-r--r--lib/AST/DeclarationName.cpp44
-rw-r--r--lib/AST/Expr.cpp212
-rw-r--r--lib/AST/ExprCXX.cpp244
-rw-r--r--lib/AST/ExprConstant.cpp62
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp259
-rw-r--r--lib/AST/RecordLayoutBuilder.h20
-rw-r--r--lib/AST/Stmt.cpp6
-rw-r--r--lib/AST/StmtDumper.cpp3
-rw-r--r--lib/AST/StmtPrinter.cpp52
-rw-r--r--lib/AST/StmtProfile.cpp46
-rw-r--r--lib/AST/StmtViz.cpp5
-rw-r--r--lib/AST/TemplateBase.cpp14
-rw-r--r--lib/AST/Type.cpp6
-rw-r--r--lib/AST/TypePrinter.cpp10
20 files changed, 918 insertions, 466 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index dc13e7f..6c9ecf0 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -48,6 +48,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
ObjCIdRedefinitionType = QualType();
ObjCClassRedefinitionType = QualType();
+ ObjCSelRedefinitionType = QualType();
if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
InitBuiltinTypes();
@@ -220,10 +221,12 @@ void ASTContext::InitBuiltinTypes() {
// "Builtin" typedefs set by Sema::ActOnTranslationUnitScope().
ObjCIdTypedefType = QualType();
ObjCClassTypedefType = QualType();
+ ObjCSelTypedefType = QualType();
- // Builtin types for 'id' and 'Class'.
+ // Builtin types for 'id', 'Class', and 'SEL'.
InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass);
+ InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel);
ObjCConstantStringType = QualType();
@@ -517,18 +520,23 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
/// getDeclAlignInBytes - Return a conservative estimate of the alignment of the
/// specified decl. Note that bitfields do not have a valid alignment, so
/// this method will assert on them.
-unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
+/// If @p RefAsPointee, references are treated like their underlying type
+/// (for alignof), else they're treated like pointers (for CodeGen).
+unsigned ASTContext::getDeclAlignInBytes(const Decl *D, bool RefAsPointee) {
unsigned Align = Target.getCharWidth();
if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
- Align = std::max(Align, AA->getAlignment());
+ Align = std::max(Align, AA->getMaxAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
- unsigned AS = RT->getPointeeType().getAddressSpace();
- Align = Target.getPointerAlign(AS);
- } else if (!T->isIncompleteType() && !T->isFunctionType()) {
+ if (RefAsPointee)
+ T = RT->getPointeeType();
+ else
+ T = getPointerType(RT->getPointeeType());
+ }
+ if (!T->isIncompleteType() && !T->isFunctionType()) {
// Incomplete or function types default to 1.
while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
T = cast<ArrayType>(T)->getElementType();
@@ -687,19 +695,21 @@ ASTContext::getTypeInfo(const Type *T) {
Align = Target.getPointerAlign(AS);
break;
}
+ case Type::LValueReference:
+ case Type::RValueReference: {
+ // alignof and sizeof should never enter this code path here, so we go
+ // the pointer route.
+ unsigned AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace();
+ Width = Target.getPointerWidth(AS);
+ Align = Target.getPointerAlign(AS);
+ break;
+ }
case Type::Pointer: {
unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace();
Width = Target.getPointerWidth(AS);
Align = Target.getPointerAlign(AS);
break;
}
- case Type::LValueReference:
- case Type::RValueReference:
- // "When applied to a reference or a reference type, the result is the size
- // of the referenced type." C++98 5.3.3p2: expr.sizeof.
- // FIXME: This is wrong for struct layout: a reference in a struct has
- // pointer size.
- return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
// FIXME: This is ABI dependent. We use the Itanium C++ ABI.
// http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
@@ -761,7 +771,8 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
- Align = Aligned->getAlignment();
+ Align = std::max(Aligned->getMaxAlignment(),
+ getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
} else
return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
@@ -1460,16 +1471,24 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals,
SourceRange Brackets) {
- assert((NumElts->isTypeDependent() || NumElts->isValueDependent()) &&
+ assert((!NumElts || NumElts->isTypeDependent() ||
+ NumElts->isValueDependent()) &&
"Size must be type- or value-dependent!");
- llvm::FoldingSetNodeID ID;
- DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
- EltTypeQuals, NumElts);
-
void *InsertPos = 0;
- DependentSizedArrayType *Canon
- = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+ DependentSizedArrayType *Canon = 0;
+
+ if (NumElts) {
+ // Dependently-sized array types that do not have a specified
+ // number of elements will have their sizes deduced from an
+ // initializer.
+ llvm::FoldingSetNodeID ID;
+ DependentSizedArrayType::Profile(ID, *this, getCanonicalType(EltTy), ASM,
+ EltTypeQuals, NumElts);
+
+ Canon = DependentSizedArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
+ }
+
DependentSizedArrayType *New;
if (Canon) {
// We already have a canonical version of this array type; use it as
@@ -1483,7 +1502,9 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy,
New = new (*this, TypeAlignment)
DependentSizedArrayType(*this, EltTy, QualType(),
NumElts, ASM, EltTypeQuals, Brackets);
- DependentSizedArrayTypes.InsertNode(New, InsertPos);
+
+ if (NumElts)
+ DependentSizedArrayTypes.InsertNode(New, InsertPos);
} else {
QualType Canon = getDependentSizedArrayType(CanonEltTy, NumElts,
ASM, EltTypeQuals,
@@ -1818,9 +1839,10 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
- const TemplateArgumentLoc *Args,
- unsigned NumArgs,
+ const TemplateArgumentListInfo &Args,
QualType Canon) {
+ unsigned NumArgs = Args.size();
+
llvm::SmallVector<TemplateArgument, 4> ArgVec;
ArgVec.reserve(NumArgs);
for (unsigned i = 0; i != NumArgs; ++i)
@@ -2320,6 +2342,22 @@ CanQualType ASTContext::getCanonicalType(QualType T) {
VAT->getBracketsRange()));
}
+DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
+ if (TemplateDecl *TD = Name.getAsTemplateDecl())
+ return TD->getDeclName();
+
+ if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+ if (DTN->isIdentifier()) {
+ return DeclarationNames.getIdentifier(DTN->getIdentifier());
+ } else {
+ return DeclarationNames.getCXXOperatorName(DTN->getOperator());
+ }
+ }
+
+ assert(Name.getAsOverloadedFunctionDecl());
+ return Name.getAsOverloadedFunctionDecl()->getDeclName();
+}
+
TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
// If this template name refers to a template, the canonical
// template name merely stores the template itself.
@@ -3374,9 +3412,14 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
false);
return;
}
-
+
if (const PointerType *PT = T->getAs<PointerType>()) {
+ if (PT->isObjCSelType()) {
+ S += ':';
+ return;
+ }
QualType PointeeTy = PT->getPointeeType();
+
bool isReadOnly = false;
// For historical/compatibility reasons, the read-only qualifier of the
// pointee gets emitted _before_ the '^'. The read-only qualifier of
@@ -3407,10 +3450,6 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S.replace(S.end()-2, S.end(), replace);
}
}
- if (isObjCSelType(PointeeTy)) {
- S += ':';
- return;
- }
if (PointeeTy->isCharType()) {
// char pointer types should be encoded as '*' unless it is a
@@ -3633,21 +3672,7 @@ void ASTContext::setObjCIdType(QualType T) {
}
void ASTContext::setObjCSelType(QualType T) {
- ObjCSelType = T;
-
- const TypedefType *TT = T->getAs<TypedefType>();
- if (!TT)
- return;
- TypedefDecl *TD = TT->getDecl();
-
- // typedef struct objc_selector *SEL;
- const PointerType *ptr = TD->getUnderlyingType()->getAs<PointerType>();
- if (!ptr)
- return;
- const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
- if (!rec)
- return;
- SelStructType = rec;
+ ObjCSelTypedefType = T;
}
void ASTContext::setObjCProtoType(QualType QT) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bdc8047..572d76f 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -211,6 +211,203 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
+static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
+ assert(D->getDeclContext()->getLookupContext()->isFileContext() &&
+ "Not a name having namespace scope");
+ ASTContext &Context = D->getASTContext();
+
+ // C++ [basic.link]p3:
+ // A name having namespace scope (3.3.6) has internal linkage if it
+ // is the name of
+ // - an object, reference, function or function template that is
+ // explicitly declared static; or,
+ // (This bullet corresponds to C99 6.2.2p3.)
+ if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ // Explicitly declared static.
+ if (Var->getStorageClass() == VarDecl::Static)
+ return NamedDecl::InternalLinkage;
+
+ // - an object or reference that is explicitly declared const
+ // and neither explicitly declared extern nor previously
+ // declared to have external linkage; or
+ // (there is no equivalent in C99)
+ if (Context.getLangOptions().CPlusPlus &&
+ Var->getType().isConstant(Context) &&
+ Var->getStorageClass() != VarDecl::Extern &&
+ Var->getStorageClass() != VarDecl::PrivateExtern) {
+ bool FoundExtern = false;
+ for (const VarDecl *PrevVar = Var->getPreviousDeclaration();
+ PrevVar && !FoundExtern;
+ PrevVar = PrevVar->getPreviousDeclaration())
+ if (PrevVar->getLinkage() == NamedDecl::ExternalLinkage)
+ FoundExtern = true;
+
+ if (!FoundExtern)
+ return NamedDecl::InternalLinkage;
+ }
+ } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+ const FunctionDecl *Function = 0;
+ if (const FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(D))
+ Function = FunTmpl->getTemplatedDecl();
+ else
+ Function = cast<FunctionDecl>(D);
+
+ // Explicitly declared static.
+ if (Function->getStorageClass() == FunctionDecl::Static)
+ return NamedDecl::InternalLinkage;
+ } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
+ // - a data member of an anonymous union.
+ if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+ return NamedDecl::InternalLinkage;
+ }
+
+ // C++ [basic.link]p4:
+
+ // A name having namespace scope has external linkage if it is the
+ // name of
+ //
+ // - an object or reference, unless it has internal linkage; or
+ if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ if (!Context.getLangOptions().CPlusPlus &&
+ (Var->getStorageClass() == VarDecl::Extern ||
+ Var->getStorageClass() == VarDecl::PrivateExtern)) {
+ // C99 6.2.2p4:
+ // For an identifier declared with the storage-class specifier
+ // extern in a scope in which a prior declaration of that
+ // identifier is visible, if the prior declaration specifies
+ // internal or external linkage, the linkage of the identifier
+ // at the later declaration is the same as the linkage
+ // specified at the prior declaration. If no prior declaration
+ // is visible, or if the prior declaration specifies no
+ // linkage, then the identifier has external linkage.
+ if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) {
+ if (NamedDecl::Linkage L = PrevVar->getLinkage())
+ return L;
+ }
+ }
+
+ // C99 6.2.2p5:
+ // If the declaration of an identifier for an object has file
+ // scope and no storage-class specifier, its linkage is
+ // external.
+ return NamedDecl::ExternalLinkage;
+ }
+
+ // - a function, unless it has internal linkage; or
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ // C99 6.2.2p5:
+ // If the declaration of an identifier for a function has no
+ // storage-class specifier, its linkage is determined exactly
+ // as if it were declared with the storage-class specifier
+ // extern.
+ if (!Context.getLangOptions().CPlusPlus &&
+ (Function->getStorageClass() == FunctionDecl::Extern ||
+ Function->getStorageClass() == FunctionDecl::PrivateExtern ||
+ Function->getStorageClass() == FunctionDecl::None)) {
+ // C99 6.2.2p4:
+ // For an identifier declared with the storage-class specifier
+ // extern in a scope in which a prior declaration of that
+ // identifier is visible, if the prior declaration specifies
+ // internal or external linkage, the linkage of the identifier
+ // at the later declaration is the same as the linkage
+ // specified at the prior declaration. If no prior declaration
+ // is visible, or if the prior declaration specifies no
+ // linkage, then the identifier has external linkage.
+ if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) {
+ if (NamedDecl::Linkage L = PrevFunc->getLinkage())
+ return L;
+ }
+ }
+
+ return NamedDecl::ExternalLinkage;
+ }
+
+ // - a named class (Clause 9), or an unnamed class defined in a
+ // typedef declaration in which the class has the typedef name
+ // for linkage purposes (7.1.3); or
+ // - a named enumeration (7.2), or an unnamed enumeration
+ // defined in a typedef declaration in which the enumeration
+ // has the typedef name for linkage purposes (7.1.3); or
+ if (const TagDecl *Tag = dyn_cast<TagDecl>(D))
+ if (Tag->getDeclName() || Tag->getTypedefForAnonDecl())
+ return NamedDecl::ExternalLinkage;
+
+ // - an enumerator belonging to an enumeration with external linkage;
+ if (isa<EnumConstantDecl>(D))
+ if (cast<NamedDecl>(D->getDeclContext())->getLinkage()
+ == NamedDecl::ExternalLinkage)
+ return NamedDecl::ExternalLinkage;
+
+ // - a template, unless it is a function template that has
+ // internal linkage (Clause 14);
+ if (isa<TemplateDecl>(D))
+ return NamedDecl::ExternalLinkage;
+
+ // - a namespace (7.3), unless it is declared within an unnamed
+ // namespace.
+ if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace())
+ return NamedDecl::ExternalLinkage;
+
+ return NamedDecl::NoLinkage;
+}
+
+NamedDecl::Linkage NamedDecl::getLinkage() const {
+ // Handle linkage for namespace-scope names.
+ if (getDeclContext()->getLookupContext()->isFileContext())
+ if (Linkage L = getLinkageForNamespaceScopeDecl(this))
+ return L;
+
+ // C++ [basic.link]p5:
+ // In addition, a member function, static data member, a named
+ // class or enumeration of class scope, or an unnamed class or
+ // enumeration defined in a class-scope typedef declaration such
+ // that the class or enumeration has the typedef name for linkage
+ // purposes (7.1.3), has external linkage if the name of the class
+ // has external linkage.
+ if (getDeclContext()->isRecord() &&
+ (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) ||
+ (isa<TagDecl>(this) &&
+ (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl()))) &&
+ cast<RecordDecl>(getDeclContext())->getLinkage() == ExternalLinkage)
+ return ExternalLinkage;
+
+ // C++ [basic.link]p6:
+ // The name of a function declared in block scope and the name of
+ // an object declared by a block scope extern declaration have
+ // linkage. If there is a visible declaration of an entity with
+ // linkage having the same name and type, ignoring entities
+ // declared outside the innermost enclosing namespace scope, the
+ // block scope declaration declares that same entity and receives
+ // the linkage of the previous declaration. If there is more than
+ // one such matching entity, the program is ill-formed. Otherwise,
+ // if no matching entity is found, the block scope entity receives
+ // external linkage.
+ if (getLexicalDeclContext()->isFunctionOrMethod()) {
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) {
+ if (Function->getPreviousDeclaration())
+ if (Linkage L = Function->getPreviousDeclaration()->getLinkage())
+ return L;
+
+ return ExternalLinkage;
+ }
+
+ if (const VarDecl *Var = dyn_cast<VarDecl>(this))
+ if (Var->getStorageClass() == VarDecl::Extern ||
+ Var->getStorageClass() == VarDecl::PrivateExtern) {
+ if (Var->getPreviousDeclaration())
+ if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
+ return L;
+
+ return ExternalLinkage;
+ }
+ }
+
+ // C++ [basic.link]p6:
+ // Names not covered by these rules have no linkage.
+ return NoLinkage;
+}
+
std::string NamedDecl::getQualifiedNameAsString() const {
return getQualifiedNameAsString(getASTContext().getLangOptions());
}
@@ -300,13 +497,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
}
bool NamedDecl::hasLinkage() const {
- if (const VarDecl *VD = dyn_cast<VarDecl>(this))
- return VD->hasExternalStorage() || VD->isFileVarDecl();
-
- if (isa<FunctionDecl>(this) && !isa<CXXMethodDecl>(this))
- return true;
-
- return false;
+ return getLinkage() != NoLinkage;
}
NamedDecl *NamedDecl::getUnderlyingDecl() {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 831f552..2dcd80b 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -55,8 +55,7 @@ const char *DeclContext::getDeclKindName() const {
}
bool Decl::CollectingStats(bool Enable) {
- if (Enable)
- StatSwitch = true;
+ if (Enable) StatSwitch = true;
return StatSwitch;
}
@@ -119,7 +118,7 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
OS << Message;
- if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
+ if (const NamedDecl *DN = dyn_cast_or_null<NamedDecl>(TheDecl))
OS << " '" << DN->getQualifiedNameAsString() << '\'';
OS << '\n';
}
@@ -130,9 +129,6 @@ void PrettyStackTraceDecl::print(llvm::raw_ostream &OS) const {
// Out-of-line virtual method providing a home for Decl.
Decl::~Decl() {
- if (isOutOfSemaDC())
- delete getMultipleDC();
-
assert(!HasAttrs && "attributes should have been freed by Destroy");
}
@@ -148,7 +144,7 @@ void Decl::setLexicalDeclContext(DeclContext *DC) {
return;
if (isInSemaDC()) {
- MultipleDC *MDC = new MultipleDC();
+ MultipleDC *MDC = new (getASTContext()) MultipleDC();
MDC->SemanticDC = getDeclContext();
MDC->LexicalDC = DC;
DeclCtx = MDC;
@@ -343,9 +339,12 @@ void Decl::Destroy(ASTContext &C) {
N = Tmp;
}
+ if (isOutOfSemaDC())
+ delete (C) getMultipleDC();
+
this->~Decl();
C.Deallocate((void *)this);
-#endif
+#endif
}
Decl *Decl::castFromDeclContext (const DeclContext *D) {
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index a21c93f..4001988 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -36,8 +36,6 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
HasTrivialDestructor(true), ComputedVisibleConversions(false),
Bases(0), NumBases(0), VBases(0), NumVBases(0),
- Conversions(DC, DeclarationName()),
- VisibleConversions(DC, DeclarationName()),
TemplateOrInstantiation() { }
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
@@ -299,14 +297,11 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
void
CXXRecordDecl::collectConversionFunctions(
- llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet)
+ llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
{
- OverloadedFunctionDecl *TopConversions = getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- TFunc = TopConversions->function_begin(),
- TFuncEnd = TopConversions->function_end();
- TFunc != TFuncEnd; ++TFunc) {
- NamedDecl *TopConv = TFunc->get();
+ const UnresolvedSet *Cs = getConversionFunctions();
+ for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ NamedDecl *TopConv = *I;
CanQualType TConvType;
if (FunctionTemplateDecl *TConversionTemplate =
dyn_cast<FunctionTemplateDecl>(TopConv))
@@ -336,14 +331,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
bool inTopClass = (RD == this);
QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
- OverloadedFunctionDecl *Conversions
+ const UnresolvedSet *Cs
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- Func = Conversions->function_begin(),
- FuncEnd = Conversions->function_end();
- Func != FuncEnd; ++Func) {
- NamedDecl *Conv = Func->get();
+ for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ NamedDecl *Conv = *I;
// Only those conversions not exact match of conversions in current
// class are candidateconversion routines.
CanQualType ConvType;
@@ -405,8 +397,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
-OverloadedFunctionDecl *
-CXXRecordDecl::getVisibleConversionFunctions() {
+const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() {
// If root class, all conversions are visible.
if (bases_begin() == bases_end())
return &Conversions;
@@ -425,26 +416,26 @@ void CXXRecordDecl::addVisibleConversionFunction(
CXXConversionDecl *ConvDecl) {
assert(!ConvDecl->getDescribedFunctionTemplate() &&
"Conversion function templates should cast to FunctionTemplateDecl.");
- VisibleConversions.addOverload(ConvDecl);
+ VisibleConversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addVisibleConversionFunction(
FunctionTemplateDecl *ConvDecl) {
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
"Function template is not a conversion function template");
- VisibleConversions.addOverload(ConvDecl);
+ VisibleConversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) {
assert(!ConvDecl->getDescribedFunctionTemplate() &&
"Conversion function templates should cast to FunctionTemplateDecl.");
- Conversions.addOverload(ConvDecl);
+ Conversions.addDecl(ConvDecl);
}
void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) {
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
"Function template is not a conversion function template");
- Conversions.addOverload(ConvDecl);
+ Conversions.addDecl(ConvDecl);
}
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
@@ -895,12 +886,21 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
- NamespaceDecl *Used,
+ NamedDecl *Used,
DeclContext *CommonAncestor) {
+ if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
+ Used = NS->getOriginalNamespace();
return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
Qualifier, IdentLoc, Used, CommonAncestor);
}
+NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
+ if (NamespaceAliasDecl *NA =
+ dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
+ return NA->getNamespace();
+ return cast_or_null<NamespaceDecl>(NominatedNamespace);
+}
+
NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation AliasLoc,
@@ -909,6 +909,8 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
NamedDecl *Namespace) {
+ if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
+ Namespace = NS->getOriginalNamespace();
return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
Qualifier, IdentLoc, Namespace);
}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 131de8b..a5982cf 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -18,19 +18,18 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyPrinter.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
namespace {
- class VISIBILITY_HIDDEN DeclPrinter : public DeclVisitor<DeclPrinter> {
+ class DeclPrinter : public DeclVisitor<DeclPrinter> {
llvm::raw_ostream &Out;
ASTContext &Context;
PrintingPolicy Policy;
unsigned Indentation;
- llvm::raw_ostream& Indent();
+ llvm::raw_ostream& Indent() { return Indent(Indentation); }
+ llvm::raw_ostream& Indent(unsigned Indentation);
void ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls);
void Print(AccessSpecifier AS);
@@ -154,8 +153,8 @@ void Decl::dump() const {
print(llvm::errs());
}
-llvm::raw_ostream& DeclPrinter::Indent() {
- for (unsigned i = 0; i < Indentation; ++i)
+llvm::raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
+ for (unsigned i = 0; i != Indentation; ++i)
Out << " ";
return Out;
}
@@ -205,6 +204,8 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
AccessSpecifier AS = D->getAccess();
if (AS != CurAS) {
+ if (Indent)
+ this->Indent(Indentation - Policy.Indentation);
Print(AS);
Out << ":\n";
CurAS = AS;
@@ -502,7 +503,7 @@ void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Out << "using namespace ";
if (D->getQualifier())
D->getQualifier()->print(Out, Policy);
- Out << D->getNominatedNamespace()->getNameAsString();
+ Out << D->getNominatedNamespaceAsWritten()->getNameAsString();
}
void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 0c14714..902339e 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -214,9 +214,7 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
} else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
- NTTP->getLocation(),
- NTTP->getType()->isDependentType(),
- /*Value-dependent=*/true);
+ NTTP->getLocation());
TemplateArgs.push_back(TemplateArgument(E));
} else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
@@ -453,8 +451,9 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
- TemplateArgumentLoc *ArgInfos, unsigned N,
+ const TemplateArgumentListInfo &ArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
+ unsigned N = ArgInfos.size();
TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
for (unsigned I = 0; I != N; ++I)
ClonedArgs[I] = ArgInfos[I];
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 1ff068c..3471657 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -50,6 +50,17 @@ public:
void *FETokenInfo;
};
+/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
+/// name.
+///
+/// This identifier is stored here rather than directly in DeclarationName so as
+/// to allow Objective-C selectors, which are about a million times more common,
+/// to consume minimal memory.
+class CXXLiteralOperatorIdName : public DeclarationNameExtra {
+public:
+ IdentifierInfo *ID;
+};
+
bool operator<(DeclarationName LHS, DeclarationName RHS) {
if (LHS.getNameKind() != RHS.getNameKind())
return LHS.getNameKind() < RHS.getNameKind();
@@ -89,6 +100,10 @@ bool operator<(DeclarationName LHS, DeclarationName RHS) {
case DeclarationName::CXXOperatorName:
return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
+
+ case DeclarationName::CXXLiteralOperatorName:
+ return LHS.getCXXLiteralIdentifier()->getName() <
+ RHS.getCXXLiteralIdentifier()->getName();
case DeclarationName::CXXUsingDirective:
return false;
@@ -143,6 +158,9 @@ DeclarationName::NameKind DeclarationName::getNameKind() const {
case DeclarationNameExtra::CXXConversionFunction:
return CXXConversionFunctionName;
+ case DeclarationNameExtra::CXXLiteralOperator:
+ return CXXLiteralOperatorName;
+
case DeclarationNameExtra::CXXUsingDirective:
return CXXUsingDirective;
@@ -208,6 +226,10 @@ std::string DeclarationName::getAsString() const {
return Result;
}
+ case CXXLiteralOperatorName: {
+ return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
+ }
+
case CXXConversionFunctionName: {
std::string Result = "operator ";
QualType Type = getCXXNameType();
@@ -242,6 +264,13 @@ OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
}
}
+IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
+ if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
+ return CXXLit->ID;
+ else
+ return 0;
+}
+
Selector DeclarationName::getObjCSelector() const {
switch (getNameKind()) {
case ObjCZeroArgSelector:
@@ -273,6 +302,9 @@ void *DeclarationName::getFETokenInfoAsVoid() const {
case CXXOperatorName:
return getAsCXXOperatorIdName()->FETokenInfo;
+ case CXXLiteralOperatorName:
+ return getCXXLiteralIdentifier()->getFETokenInfo<void>();
+
default:
assert(false && "Declaration name has no FETokenInfo");
}
@@ -295,6 +327,10 @@ void DeclarationName::setFETokenInfo(void *T) {
getAsCXXOperatorIdName()->FETokenInfo = T;
break;
+ case CXXLiteralOperatorName:
+ getCXXLiteralIdentifier()->setFETokenInfo(T);
+ break;
+
default:
assert(false && "Declaration name has no FETokenInfo");
}
@@ -390,6 +426,14 @@ DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
}
+DeclarationName
+DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
+ CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
+ LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
+ LiteralName->ID = II;
+ return DeclarationName(LiteralName);
+}
+
unsigned
llvm::DenseMapInfo<clang::DeclarationName>::
getHashValue(clang::DeclarationName N) {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 90b50c6..624a620 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -31,49 +31,104 @@ using namespace clang;
// Primary Expressions.
//===----------------------------------------------------------------------===//
+void ExplicitTemplateArgumentList::initializeFrom(
+ const TemplateArgumentListInfo &Info) {
+ LAngleLoc = Info.getLAngleLoc();
+ RAngleLoc = Info.getRAngleLoc();
+ NumTemplateArgs = Info.size();
+
+ TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
+ for (unsigned i = 0; i != NumTemplateArgs; ++i)
+ new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
+}
+
+void ExplicitTemplateArgumentList::copyInto(
+ TemplateArgumentListInfo &Info) const {
+ Info.setLAngleLoc(LAngleLoc);
+ Info.setRAngleLoc(RAngleLoc);
+ for (unsigned I = 0; I != NumTemplateArgs; ++I)
+ Info.addArgument(getTemplateArgs()[I]);
+}
+
+std::size_t ExplicitTemplateArgumentList::sizeFor(
+ const TemplateArgumentListInfo &Info) {
+ return sizeof(ExplicitTemplateArgumentList) +
+ sizeof(TemplateArgumentLoc) * Info.size();
+}
+
+void DeclRefExpr::computeDependence() {
+ TypeDependent = false;
+ ValueDependent = false;
+
+ NamedDecl *D = getDecl();
+
+ // (TD) C++ [temp.dep.expr]p3:
+ // An id-expression is type-dependent if it contains:
+ //
+ // and
+ //
+ // (VD) C++ [temp.dep.constexpr]p2:
+ // An identifier is value-dependent if it is:
+
+ // (TD) - an identifier that was declared with dependent type
+ // (VD) - a name declared with a dependent type,
+ if (getType()->isDependentType()) {
+ TypeDependent = true;
+ ValueDependent = true;
+ }
+ // (TD) - a conversion-function-id that specifies a dependent type
+ else if (D->getDeclName().getNameKind()
+ == DeclarationName::CXXConversionFunctionName &&
+ D->getDeclName().getCXXNameType()->isDependentType()) {
+ TypeDependent = true;
+ ValueDependent = true;
+ }
+ // (TD) - a template-id that is dependent,
+ else if (hasExplicitTemplateArgumentList() &&
+ TemplateSpecializationType::anyDependentTemplateArguments(
+ getTemplateArgs(),
+ getNumTemplateArgs())) {
+ TypeDependent = true;
+ ValueDependent = true;
+ }
+ // (VD) - the name of a non-type template parameter,
+ else if (isa<NonTypeTemplateParmDecl>(D))
+ ValueDependent = true;
+ // (VD) - a constant with integral or enumeration type and is
+ // initialized with an expression that is value-dependent.
+ else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ if (Var->getType()->isIntegralType() &&
+ Var->getType().getCVRQualifiers() == Qualifiers::Const &&
+ Var->getInit() &&
+ Var->getInit()->isValueDependent())
+ ValueDependent = true;
+ }
+ // (TD) - a nested-name-specifier or a qualified-id that names a
+ // member of an unknown specialization.
+ // (handled by DependentScopeDeclRefExpr)
+}
+
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD)
- : Expr(DeclRefExprClass, T, TD, VD),
+ const TemplateArgumentListInfo *TemplateArgs,
+ QualType T)
+ : Expr(DeclRefExprClass, T, false, false),
DecoratedD(D,
(Qualifier? HasQualifierFlag : 0) |
- (HasExplicitTemplateArgumentList?
- HasExplicitTemplateArgumentListFlag : 0)),
+ (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
Loc(NameLoc) {
+ assert(!isa<OverloadedFunctionDecl>(D));
if (Qualifier) {
NameQualifier *NQ = getNameQualifier();
NQ->NNS = Qualifier;
NQ->Range = QualifierRange;
}
- if (HasExplicitTemplateArgumentList) {
- ExplicitTemplateArgumentList *ETemplateArgs
- = getExplicitTemplateArgumentList();
- ETemplateArgs->LAngleLoc = LAngleLoc;
- ETemplateArgs->RAngleLoc = RAngleLoc;
- ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
-
- TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
- for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
- new (TemplateArgs + I) TemplateArgumentLoc(ExplicitTemplateArgs[I]);
- }
-}
+ if (TemplateArgs)
+ getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
-DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- NamedDecl *D,
- SourceLocation NameLoc,
- QualType T, bool TD, bool VD) {
- return Create(Context, Qualifier, QualifierRange, D, NameLoc,
- false, SourceLocation(), 0, 0, SourceLocation(),
- T, TD, VD);
+ computeDependence();
}
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@@ -81,28 +136,18 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD) {
+ QualType T,
+ const TemplateArgumentListInfo *TemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (Qualifier != 0)
Size += sizeof(NameQualifier);
- if (HasExplicitTemplateArgumentList)
- Size += sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgumentLoc) * NumExplicitTemplateArgs;
+ if (TemplateArgs)
+ Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
- HasExplicitTemplateArgumentList,
- LAngleLoc,
- ExplicitTemplateArgs,
- NumExplicitTemplateArgs,
- RAngleLoc,
- T, TD, VD);
+ TemplateArgs, T);
}
SourceRange DeclRefExpr::getSourceRange() const {
@@ -427,15 +472,13 @@ QualType CallExpr::getCallReturnType() const {
MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl,
- SourceLocation l, bool has_explicit,
- SourceLocation langle,
- const TemplateArgumentLoc *targs, unsigned numtargs,
- SourceLocation rangle, QualType ty)
+ SourceLocation l, const TemplateArgumentListInfo *targs,
+ QualType ty)
: Expr(MemberExprClass, ty,
base->isTypeDependent() || (qual && qual->isDependent()),
base->isValueDependent() || (qual && qual->isDependent())),
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
- HasQualifier(qual != 0), HasExplicitTemplateArgumentList(has_explicit) {
+ HasQualifier(qual != 0), HasExplicitTemplateArgumentList(targs) {
// Initialize the qualifier, if any.
if (HasQualifier) {
NameQualifier *NQ = getMemberQualifier();
@@ -444,17 +487,8 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
}
// Initialize the explicit template argument list, if any.
- if (HasExplicitTemplateArgumentList) {
- ExplicitTemplateArgumentList *ETemplateArgs
- = getExplicitTemplateArgumentList();
- ETemplateArgs->LAngleLoc = langle;
- ETemplateArgs->RAngleLoc = rangle;
- ETemplateArgs->NumTemplateArgs = numtargs;
-
- TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
- for (unsigned I = 0; I < numtargs; ++I)
- new (TemplateArgs + I) TemplateArgumentLoc(targs[I]);
- }
+ if (targs)
+ getExplicitTemplateArgumentList()->initializeFrom(*targs);
}
MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
@@ -462,24 +496,18 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
SourceRange qualrange,
NamedDecl *memberdecl,
SourceLocation l,
- bool has_explicit,
- SourceLocation langle,
- const TemplateArgumentLoc *targs,
- unsigned numtargs,
- SourceLocation rangle,
+ const TemplateArgumentListInfo *targs,
QualType ty) {
std::size_t Size = sizeof(MemberExpr);
if (qual != 0)
Size += sizeof(NameQualifier);
- if (has_explicit)
- Size += sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgumentLoc) * numtargs;
+ if (targs)
+ Size += ExplicitTemplateArgumentList::sizeFor(*targs);
void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l,
- has_explicit, langle, targs, numtargs, rangle,
- ty);
+ targs, ty);
}
const char *CastExpr::getCastKindName() const {
@@ -528,6 +556,8 @@ const char *CastExpr::getCastKindName() const {
return "FloatingToIntegral";
case CastExpr::CK_FloatingCast:
return "FloatingCast";
+ case CastExpr::CK_MemberPointerToBoolean:
+ return "MemberPointerToBoolean";
}
assert(0 && "Unhandled cast kind!");
@@ -640,12 +670,17 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
InitListExpr::InitListExpr(SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc)
- : Expr(InitListExprClass, QualType(),
- hasAnyTypeDependentArguments(initExprs, numInits),
- hasAnyValueDependentArguments(initExprs, numInits)),
+ : Expr(InitListExprClass, QualType(), false, false),
LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
- UnionFieldInit(0), HadArrayRangeDesignator(false) {
-
+ UnionFieldInit(0), HadArrayRangeDesignator(false)
+{
+ for (unsigned I = 0; I != numInits; ++I) {
+ if (initExprs[I]->isTypeDependent())
+ TypeDependent = true;
+ if (initExprs[I]->isValueDependent())
+ ValueDependent = true;
+ }
+
InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
}
@@ -1091,10 +1126,10 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
return LV_Valid;
case PredefinedExprClass:
return LV_Valid;
+ case UnresolvedLookupExprClass:
+ return LV_Valid;
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
- case CXXConditionDeclExprClass:
- return LV_Valid;
case CStyleCastExprClass:
case CXXFunctionalCastExprClass:
case CXXStaticCastExprClass:
@@ -1141,18 +1176,6 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
return LV_Valid;
}
- case TemplateIdRefExprClass: {
- const TemplateIdRefExpr *TID = cast<TemplateIdRefExpr>(this);
- TemplateName Template = TID->getTemplateName();
- NamedDecl *ND = Template.getAsTemplateDecl();
- if (!ND)
- ND = Template.getAsOverloadedFunctionDecl();
- if (ND && DeclCanBeLvalue(ND, Ctx))
- return LV_Valid;
-
- break;
- }
-
default:
break;
}
@@ -1491,19 +1514,18 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
case Expr::CXXNullPtrLiteralExprClass:
case Expr::CXXThisExprClass:
case Expr::CXXThrowExprClass:
- case Expr::CXXConditionDeclExprClass: // FIXME: is this correct?
case Expr::CXXNewExprClass:
case Expr::CXXDeleteExprClass:
case Expr::CXXPseudoDestructorExprClass:
- case Expr::UnresolvedFunctionNameExprClass:
- case Expr::UnresolvedDeclRefExprClass:
- case Expr::TemplateIdRefExprClass:
+ case Expr::UnresolvedLookupExprClass:
+ case Expr::DependentScopeDeclRefExprClass:
case Expr::CXXConstructExprClass:
case Expr::CXXBindTemporaryExprClass:
case Expr::CXXExprWithTemporariesClass:
case Expr::CXXTemporaryObjectExprClass:
case Expr::CXXUnresolvedConstructExprClass:
- case Expr::CXXUnresolvedMemberExprClass:
+ case Expr::CXXDependentScopeMemberExprClass:
+ case Expr::UnresolvedMemberExprClass:
case Expr::ObjCStringLiteralClass:
case Expr::ObjCEncodeExprClass:
case Expr::ObjCMessageExprClass:
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 0ba4608..d1a0390 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -72,14 +72,6 @@ Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
return child_iterator();
}
-// CXXConditionDeclExpr
-Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
- return getVarDecl();
-}
-Stmt::child_iterator CXXConditionDeclExpr::child_end() {
- return child_iterator();
-}
-
// CXXNewExpr
CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
Expr **placementArgs, unsigned numPlaceArgs,
@@ -121,11 +113,45 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
return &Base + 1;
}
-// UnresolvedFunctionNameExpr
-Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
+// UnresolvedLookupExpr
+UnresolvedLookupExpr *
+UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange, DeclarationName Name,
+ SourceLocation NameLoc, bool ADL,
+ const TemplateArgumentListInfo &Args)
+{
+ void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
+ ExplicitTemplateArgumentList::sizeFor(Args));
+ UnresolvedLookupExpr *ULE
+ = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+ Dependent, Qualifier, QualifierRange,
+ Name, NameLoc, ADL,
+ /*Overload*/ true,
+ /*ExplicitTemplateArgs*/ true);
+
+ reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
+
+ return ULE;
+}
+
+bool UnresolvedLookupExpr::ComputeDependence(NamedDecl * const *Begin,
+ NamedDecl * const *End,
+ const TemplateArgumentListInfo *Args) {
+ for (NamedDecl * const *I = Begin; I != End; ++I)
+ if ((*I)->getDeclContext()->isDependentContext())
+ return true;
+
+ if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
+ return true;
+
+ return false;
+}
+
+Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
return child_iterator();
}
-Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
+Stmt::child_iterator UnresolvedLookupExpr::child_end() {
return child_iterator();
}
// UnaryTypeTraitExpr
@@ -136,72 +162,37 @@ Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
return child_iterator();
}
-// UnresolvedDeclRefExpr
-StmtIterator UnresolvedDeclRefExpr::child_begin() {
- return child_iterator();
+// DependentScopeDeclRefExpr
+DependentScopeDeclRefExpr *
+DependentScopeDeclRefExpr::Create(ASTContext &C,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo *Args) {
+ std::size_t size = sizeof(DependentScopeDeclRefExpr);
+ if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
+ void *Mem = C.Allocate(size);
+
+ DependentScopeDeclRefExpr *DRE
+ = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
+ Qualifier, QualifierRange,
+ Name, NameLoc,
+ Args != 0);
+
+ if (Args)
+ reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
+ ->initializeFrom(*Args);
+
+ return DRE;
}
-StmtIterator UnresolvedDeclRefExpr::child_end() {
+StmtIterator DependentScopeDeclRefExpr::child_begin() {
return child_iterator();
}
-TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- TemplateName Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc)
- : Expr(TemplateIdRefExprClass, T,
- (Template.isDependent() ||
- TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, NumTemplateArgs)),
- (Template.isDependent() ||
- TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, NumTemplateArgs))),
- Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
- TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
- RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs) {
- TemplateArgumentLoc *StoredTemplateArgs
- = reinterpret_cast<TemplateArgumentLoc *> (this+1);
- for (unsigned I = 0; I != NumTemplateArgs; ++I)
- new (StoredTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
-}
-
-TemplateIdRefExpr *
-TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
- void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
- sizeof(TemplateArgumentLoc) * NumTemplateArgs);
- return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
- TemplateNameLoc, LAngleLoc, TemplateArgs,
- NumTemplateArgs, RAngleLoc);
-}
-
-void TemplateIdRefExpr::DoDestroy(ASTContext &Context) {
- const TemplateArgumentLoc *TemplateArgs = getTemplateArgs();
- for (unsigned I = 0; I != NumTemplateArgs; ++I)
- if (Expr *E = TemplateArgs[I].getArgument().getAsExpr())
- E->Destroy(Context);
- this->~TemplateIdRefExpr();
- Context.Deallocate(this);
-}
-
-Stmt::child_iterator TemplateIdRefExpr::child_begin() {
- // FIXME: Walk the expressions in the template arguments (?)
- return Stmt::child_iterator();
-}
-
-Stmt::child_iterator TemplateIdRefExpr::child_end() {
- // FIXME: Walk the expressions in the template arguments (?)
- return Stmt::child_iterator();
+StmtIterator DependentScopeDeclRefExpr::child_end() {
+ return child_iterator();
}
bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
@@ -526,7 +517,7 @@ Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
}
-CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C,
+CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -534,33 +525,20 @@ CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C,
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc)
- : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
+ const TemplateArgumentListInfo *TemplateArgs)
+ : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Base(Base), IsArrow(IsArrow),
- HasExplicitTemplateArgumentList(HasExplicitTemplateArgs),
+ HasExplicitTemplateArgumentList(TemplateArgs),
OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) {
- if (HasExplicitTemplateArgumentList) {
- ExplicitTemplateArgumentList *ETemplateArgs
- = getExplicitTemplateArgumentList();
- ETemplateArgs->LAngleLoc = LAngleLoc;
- ETemplateArgs->RAngleLoc = RAngleLoc;
- ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
-
- TemplateArgumentLoc *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
- for (unsigned I = 0; I < NumTemplateArgs; ++I)
- new (SavedTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
- }
+ if (TemplateArgs)
+ getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
}
-CXXUnresolvedMemberExpr *
-CXXUnresolvedMemberExpr::Create(ASTContext &C,
+CXXDependentScopeMemberExpr *
+CXXDependentScopeMemberExpr::Create(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -568,37 +546,79 @@ CXXUnresolvedMemberExpr::Create(ASTContext &C,
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc) {
- if (!HasExplicitTemplateArgs)
- return new (C) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+ const TemplateArgumentListInfo *TemplateArgs) {
+ if (!TemplateArgs)
+ return new (C) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Qualifier, QualifierRange,
FirstQualifierFoundInScope,
Member, MemberLoc);
- void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) +
- sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgumentLoc) * NumTemplateArgs,
- llvm::alignof<CXXUnresolvedMemberExpr>());
- return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
+ std::size_t size = sizeof(CXXDependentScopeMemberExpr);
+ if (TemplateArgs)
+ size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
+
+ void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
+ return new (Mem) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Qualifier, QualifierRange,
FirstQualifierFoundInScope,
Member,
MemberLoc,
- HasExplicitTemplateArgs,
- LAngleLoc,
- TemplateArgs,
- NumTemplateArgs,
- RAngleLoc);
+ TemplateArgs);
+}
+
+Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
+ return child_iterator(&Base);
}
-Stmt::child_iterator CXXUnresolvedMemberExpr::child_begin() {
+Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
+ return child_iterator(&Base + 1);
+}
+
+UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
+ bool HasUnresolvedUsing,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName MemberName,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs)
+ : Expr(UnresolvedMemberExprClass, T, Dependent, Dependent),
+ Base(Base), IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
+ HasExplicitTemplateArgs(TemplateArgs != 0),
+ OperatorLoc(OperatorLoc),
+ Qualifier(Qualifier), QualifierRange(QualifierRange),
+ MemberName(MemberName), MemberLoc(MemberLoc) {
+ if (TemplateArgs)
+ getExplicitTemplateArgs()->initializeFrom(*TemplateArgs);
+}
+
+UnresolvedMemberExpr *
+UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
+ bool HasUnresolvedUsing,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs) {
+ std::size_t size = sizeof(UnresolvedMemberExpr);
+ if (TemplateArgs)
+ size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
+
+ void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
+ return new (Mem) UnresolvedMemberExpr(
+ Dependent ? C.DependentTy : C.OverloadTy,
+ Dependent, HasUnresolvedUsing, Base, IsArrow,
+ OperatorLoc, Qualifier, QualifierRange,
+ Member, MemberLoc, TemplateArgs);
+}
+
+Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
return child_iterator(&Base);
}
-Stmt::child_iterator CXXUnresolvedMemberExpr::child_end() {
+Stmt::child_iterator UnresolvedMemberExpr::child_end() {
return child_iterator(&Base + 1);
}
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 2689859..a20e1cc 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -19,7 +19,6 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Compiler.h"
#include <cstring>
using namespace clang;
@@ -153,7 +152,7 @@ static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType,
}
namespace {
-class VISIBILITY_HIDDEN HasSideEffect
+class HasSideEffect
: public StmtVisitor<HasSideEffect, bool> {
EvalInfo &Info;
public:
@@ -210,7 +209,7 @@ public:
// LValue Evaluation
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN LValueExprEvaluator
+class LValueExprEvaluator
: public StmtVisitor<LValueExprEvaluator, APValue> {
EvalInfo &Info;
public:
@@ -353,7 +352,7 @@ APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) {
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN PointerExprEvaluator
+class PointerExprEvaluator
: public StmtVisitor<PointerExprEvaluator, APValue> {
EvalInfo &Info;
public:
@@ -508,7 +507,7 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
//===----------------------------------------------------------------------===//
namespace {
- class VISIBILITY_HIDDEN VectorExprEvaluator
+ class VectorExprEvaluator
: public StmtVisitor<VectorExprEvaluator, APValue> {
EvalInfo &Info;
APValue GetZeroVector(QualType VecType);
@@ -702,7 +701,7 @@ APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN IntExprEvaluator
+class IntExprEvaluator
: public StmtVisitor<IntExprEvaluator, bool> {
EvalInfo &Info;
APValue &Result;
@@ -776,7 +775,20 @@ public:
T1.getUnqualifiedType()),
E);
}
- bool VisitDeclRefExpr(const DeclRefExpr *E);
+
+ bool CheckReferencedDecl(const Expr *E, const Decl *D);
+ bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ return CheckReferencedDecl(E, E->getDecl());
+ }
+ bool VisitMemberExpr(const MemberExpr *E) {
+ if (CheckReferencedDecl(E, E->getMemberDecl())) {
+ // Conservatively assume a MemberExpr will have side-effects
+ Info.EvalResult.HasSideEffects = true;
+ return true;
+ }
+ return false;
+ }
+
bool VisitCallExpr(const CallExpr *E);
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitUnaryOperator(const UnaryOperator *E);
@@ -834,12 +846,12 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
return true;
}
-bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
+bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
// Enums are integer constant exprs.
- if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
+ if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
// FIXME: This is an ugly hack around the fact that enums don't set their
// signedness consistently; see PR3173.
- APSInt SI = D->getInitVal();
+ APSInt SI = ECD->getInitVal();
SI.setIsUnsigned(!E->getType()->isSignedIntegerType());
// FIXME: This is an ugly hack around the fact that enums don't
// set their width (!?!) consistently; see PR3173.
@@ -851,15 +863,15 @@ bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
// In C, they can also be folded, although they are not ICEs.
if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers()
== Qualifiers::Const) {
- if (const VarDecl *D = dyn_cast<VarDecl>(E->getDecl())) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
const VarDecl *Def = 0;
- if (const Expr *Init = D->getDefinition(Def)) {
- if (APValue *V = D->getEvaluatedValue())
+ if (const Expr *Init = VD->getDefinition(Def)) {
+ if (APValue *V = VD->getEvaluatedValue())
return Success(V->getInt(), E);
if (Visit(const_cast<Expr*>(Init))) {
// Cache the evaluated value in the variable declaration.
- D->setEvaluatedValue(Info.Ctx, Result);
+ VD->setEvaluatedValue(Info.Ctx, Result);
return true;
}
@@ -1244,6 +1256,13 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
}
unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
+ // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+ // the result is the size of the referenced type."
+ // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+ // result shall be the alignment of the referenced type."
+ if (const ReferenceType *Ref = T->getAs<ReferenceType>())
+ T = Ref->getPointeeType();
+
// Get information about the alignment.
unsigned CharSize = Info.Ctx.Target.getCharWidth();
@@ -1257,10 +1276,11 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
// alignof decl is always accepted, even if it doesn't make sense: we default
// to 1 in those cases.
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
- return Info.Ctx.getDeclAlignInBytes(DRE->getDecl());
+ return Info.Ctx.getDeclAlignInBytes(DRE->getDecl(), /*RefAsPointee*/true);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
- return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl());
+ return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl(),
+ /*RefAsPointee*/true);
return GetAlignOfType(E->getType());
}
@@ -1280,6 +1300,12 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
}
QualType SrcTy = E->getTypeOfArgument();
+ // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
+ // the result is the size of the referenced type."
+ // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
+ // result shall be the alignment of the referenced type."
+ if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>())
+ SrcTy = Ref->getPointeeType();
// sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
// extension.
@@ -1460,7 +1486,7 @@ bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN FloatExprEvaluator
+class FloatExprEvaluator
: public StmtVisitor<FloatExprEvaluator, bool> {
EvalInfo &Info;
APFloat &Result;
@@ -1652,7 +1678,7 @@ bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
//===----------------------------------------------------------------------===//
namespace {
-class VISIBILITY_HIDDEN ComplexExprEvaluator
+class ComplexExprEvaluator
: public StmtVisitor<ComplexExprEvaluator, APValue> {
EvalInfo &Info;
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index b9cfcfe..326a1dc 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -14,7 +14,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
#include "clang/Basic/TargetInfo.h"
#include <llvm/ADT/SmallSet.h>
#include <llvm/Support/MathExtras.h>
@@ -22,9 +21,9 @@
using namespace clang;
ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
- : Ctx(Ctx), Size(0), Alignment(8), Packed(false), MaxFieldAlignment(0),
- DataSize(0), IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8),
- PrimaryBase(0), PrimaryBaseWasVirtual(false) {}
+ : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
+ MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0),
+ NonVirtualAlignment(8) { }
/// LayoutVtable - Lay out the vtable and set PrimaryBase.
void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
@@ -34,7 +33,7 @@ void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
}
SelectPrimaryBase(RD);
- if (PrimaryBase == 0) {
+ if (!PrimaryBase.getBase()) {
int AS = 0;
UpdateAlignment(Ctx.Target.getPointerAlign(AS));
Size += Ctx.Target.getPointerWidth(AS);
@@ -52,7 +51,7 @@ ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first.
- if (Base != PrimaryBase || PrimaryBaseWasVirtual)
+ if (Base != PrimaryBase.getBase() || PrimaryBase.isVirtual())
LayoutBaseNonVirtually(Base, false);
}
}
@@ -74,12 +73,13 @@ bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
}
void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
- const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+ const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
+ Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo();
// If the record has a primary base class that is virtual, add it to the set
// of primary bases.
- if (Layout.getPrimaryBaseWasVirtual())
- IndirectPrimaryBases.insert(Layout.getPrimaryBase());
+ if (BaseInfo.isVirtual())
+ IndirectPrimaryBases.insert(BaseInfo.getBase());
// Now traverse all bases and find primary bases for them.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
@@ -107,7 +107,7 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (!i->isVirtual()) {
SelectPrimaryVBase(Base, FirstPrimary);
- if (PrimaryBase)
+ if (PrimaryBase.getBase())
return;
continue;
}
@@ -115,7 +115,7 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
if (FirstPrimary==0)
FirstPrimary = Base;
if (!IndirectPrimaryBases.count(Base)) {
- setPrimaryBase(Base, true);
+ setPrimaryBase(Base, /*IsVirtual=*/true);
return;
}
}
@@ -141,14 +141,17 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
// base class, if one exists.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
- if (!i->isVirtual()) {
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- if (Base->isDynamicClass()) {
- // We found it.
- setPrimaryBase(Base, false);
- return;
- }
+ // Ignore virtual bases.
+ if (i->isVirtual())
+ continue;
+
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+ if (Base->isDynamicClass()) {
+ // We found it.
+ PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
+ return;
}
}
@@ -166,8 +169,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
// Otherwise if is the first nearly empty virtual base, if one exists,
// otherwise there is no primary base class.
- if (!PrimaryBase)
- setPrimaryBase(FirstPrimary, true);
+ if (!PrimaryBase.getBase())
+ setPrimaryBase(FirstPrimary, /*IsVirtual=*/true);
}
void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
@@ -232,9 +235,10 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
}
if (Base->getNumVBases()) {
- const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base);
- const CXXRecordDecl *PB = L.getPrimaryBase();
- LayoutVirtualBases(Class, Base, PB, BaseOffset, mark, IndirectPrimary);
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
+ const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().getBase();
+ LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark,
+ IndirectPrimary);
}
}
}
@@ -448,17 +452,17 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
MaxFieldAlignment = PPA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- UpdateAlignment(AA->getAlignment());
+ UpdateAlignment(AA->getMaxAlignment());
// If this is a C++ class, lay out the vtable and the non-virtual bases.
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
if (RD) {
LayoutVtable(RD);
// PrimaryBase goes first.
- if (PrimaryBase) {
- if (PrimaryBaseWasVirtual)
- IndirectPrimaryBases.insert(PrimaryBase);
- LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
+ if (PrimaryBase.getBase()) {
+ if (PrimaryBase.isVirtual())
+ IndirectPrimaryBases.insert(PrimaryBase.getBase());
+ LayoutBaseNonVirtually(PrimaryBase.getBase(), PrimaryBase.isVirtual());
}
LayoutNonVirtualBases(RD);
}
@@ -470,7 +474,8 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
if (RD) {
llvm::SmallSet<const CXXRecordDecl*, 32> mark;
- LayoutVirtualBases(RD, RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
+ LayoutVirtualBases(RD, RD, PrimaryBase.getBase(),
+ 0, mark, IndirectPrimaryBases);
}
// Finally, round the size of the total struct up to the alignment of the
@@ -498,7 +503,7 @@ void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
MaxFieldAlignment = PPA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- UpdateAlignment(AA->getAlignment());
+ UpdateAlignment(AA->getMaxAlignment());
// Layout each ivar sequentially.
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
@@ -519,84 +524,111 @@ void ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
LayoutField(*Field);
}
+void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
+ bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
+ uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
+ uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
+
+ std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
+ uint64_t TypeSize = FieldInfo.first;
+ unsigned FieldAlign = FieldInfo.second;
+
+ if (FieldPacked)
+ FieldAlign = 1;
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+
+ // The maximum field alignment overrides the aligned attribute.
+ if (MaxFieldAlignment)
+ FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+
+ // Check if we need to add padding to give the field the correct
+ // alignment.
+ if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
+ FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+
+ // Padding members don't affect overall alignment
+ if (!D->getIdentifier())
+ FieldAlign = 1;
+
+ // Place this field at the current location.
+ FieldOffsets.push_back(FieldOffset);
+
+ // Update DataSize to include the last byte containing (part of) the bitfield.
+ if (IsUnion) {
+ // FIXME: I think FieldSize should be TypeSize here.
+ DataSize = std::max(DataSize, FieldSize);
+ } else {
+ uint64_t NewSizeInBits = FieldOffset + FieldSize;
+
+ DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
+ UnfilledBitsInLastByte = DataSize - NewSizeInBits;
+ }
+
+ // Update the size.
+ Size = std::max(Size, DataSize);
+
+ // Remember max struct/class alignment.
+ UpdateAlignment(FieldAlign);
+}
+
void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
- bool FieldPacked = Packed;
+ if (D->isBitField()) {
+ LayoutBitField(D);
+ return;
+ }
+
+ // Reset the unfilled bits.
+ UnfilledBitsInLastByte = 0;
+
+ bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
uint64_t FieldOffset = IsUnion ? 0 : DataSize;
uint64_t FieldSize;
unsigned FieldAlign;
-
- FieldPacked |= D->hasAttr<PackedAttr>();
-
- if (const Expr *BitWidthExpr = D->getBitWidth()) {
- // TODO: Need to check this algorithm on other targets!
- // (tested on Linux-X86)
- FieldSize = BitWidthExpr->EvaluateAsInt(Ctx).getZExtValue();
-
+
+ if (D->getType()->isIncompleteArrayType()) {
+ // This is a flexible array member; we can't directly
+ // query getTypeInfo about these, so we figure it out here.
+ // Flexible array members don't have any size, but they
+ // have to be aligned appropriately for their element type.
+ FieldSize = 0;
+ const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
+ FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
+ } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
+ unsigned AS = RT->getPointeeType().getAddressSpace();
+ FieldSize = Ctx.Target.getPointerWidth(AS);
+ FieldAlign = Ctx.Target.getPointerAlign(AS);
+ } else {
std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
- uint64_t TypeSize = FieldInfo.first;
-
+ FieldSize = FieldInfo.first;
FieldAlign = FieldInfo.second;
+ }
- if (FieldPacked)
- FieldAlign = 1;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
- // The maximum field alignment overrides the aligned attribute.
- if (MaxFieldAlignment)
- FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
-
- // Check if we need to add padding to give the field the correct
- // alignment.
- if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
-
- // Padding members don't affect overall alignment
- if (!D->getIdentifier())
- FieldAlign = 1;
- } else {
- if (D->getType()->isIncompleteArrayType()) {
- // This is a flexible array member; we can't directly
- // query getTypeInfo about these, so we figure it out here.
- // Flexible array members don't have any size, but they
- // have to be aligned appropriately for their element type.
- FieldSize = 0;
- const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
- FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
- } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
- unsigned AS = RT->getPointeeType().getAddressSpace();
- FieldSize = Ctx.Target.getPointerWidth(AS);
- FieldAlign = Ctx.Target.getPointerAlign(AS);
- } else {
- std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
- FieldSize = FieldInfo.first;
- FieldAlign = FieldInfo.second;
- }
+ if (FieldPacked)
+ FieldAlign = 8;
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
- if (FieldPacked)
- FieldAlign = 8;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
- // The maximum field alignment overrides the aligned attribute.
- if (MaxFieldAlignment)
- FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+ // The maximum field alignment overrides the aligned attribute.
+ if (MaxFieldAlignment)
+ FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
- // Round up the current record size to the field's alignment boundary.
- FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
-
- if (!IsUnion) {
- while (true) {
- // Check if we can place the field at this offset.
- if (canPlaceFieldAtOffset(D, FieldOffset))
- break;
-
- // We couldn't place the field at the offset. Try again at a new offset.
- FieldOffset += FieldAlign;
- }
+ // Round up the current record size to the field's alignment boundary.
+ FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+
+ if (!IsUnion) {
+ while (true) {
+ // Check if we can place the field at this offset.
+ if (canPlaceFieldAtOffset(D, FieldOffset))
+ break;
- UpdateEmptyClassOffsets(D, FieldOffset);
+ // We couldn't place the field at the offset. Try again at a new offset.
+ FieldOffset += FieldAlign;
}
+
+ UpdateEmptyClassOffsets(D, FieldOffset);
}
-
+
// Place this field at the current location.
FieldOffsets.push_back(FieldOffset);
@@ -619,7 +651,7 @@ void ASTRecordLayoutBuilder::FinishLayout() {
Size = 8;
// Finally, round the size of the record up to the alignment of the
// record itself.
- Size = (Size + (Alignment-1)) & ~(Alignment-1);
+ Size = llvm::RoundUpToAlignment(Size, Alignment);
}
void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
@@ -631,6 +663,31 @@ void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
Alignment = NewAlignment;
}
+static const CXXMethodDecl *GetKeyFunction(const CXXRecordDecl *RD) {
+ if (!RD->isDynamicClass())
+ return 0;
+
+ for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+ E = RD->method_end(); I != E; ++I) {
+ const CXXMethodDecl *MD = *I;
+
+ if (!MD->isVirtual())
+ continue;
+
+ if (MD->isPure())
+ continue;
+
+ const FunctionDecl *fn;
+ if (MD->getBody(fn) && !fn->isOutOfLine())
+ continue;
+
+ // We found it.
+ return MD;
+ }
+
+ return 0;
+}
+
const ASTRecordLayout *
ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
const RecordDecl *D) {
@@ -654,17 +711,19 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
+ const CXXMethodDecl *KeyFunction = GetKeyFunction(cast<CXXRecordDecl>(D));
+
return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size(),
NonVirtualSize,
Builder.NonVirtualAlignment,
Builder.PrimaryBase,
- Builder.PrimaryBaseWasVirtual,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
- Builder.VBases.size());
+ Builder.VBases.size(),
+ KeyFunction);
}
const ASTRecordLayout *
diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h
index 0770723..69e0498 100644
--- a/lib/AST/RecordLayoutBuilder.h
+++ b/lib/AST/RecordLayoutBuilder.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
#define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
+#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/System/DataTypes.h"
@@ -27,12 +28,21 @@ namespace clang {
class ASTRecordLayoutBuilder {
ASTContext &Ctx;
+ /// Size - The current size of the record layout.
uint64_t Size;
+
+ /// Alignment - The current alignment of the record layout.
unsigned Alignment;
+
llvm::SmallVector<uint64_t, 16> FieldOffsets;
/// Packed - Whether the record is packed or not.
bool Packed;
+
+ /// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
+ /// this contains the number of bits in the last byte that can be used for
+ /// an adjacent bitfield if necessary.
+ unsigned char UnfilledBitsInLastByte;
/// MaxFieldAlignment - The maximum allowed field alignment. This is set by
/// #pragma pack.
@@ -45,8 +55,8 @@ class ASTRecordLayoutBuilder {
uint64_t NonVirtualSize;
unsigned NonVirtualAlignment;
- const CXXRecordDecl *PrimaryBase;
- bool PrimaryBaseWasVirtual;
+
+ ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
typedef llvm::SmallVector<std::pair<const CXXRecordDecl *,
uint64_t>, 4> BaseOffsetsTy;
@@ -74,6 +84,7 @@ class ASTRecordLayoutBuilder {
void LayoutFields(const RecordDecl *D);
void LayoutField(const FieldDecl *D);
+ void LayoutBitField(const FieldDecl *D);
void SelectPrimaryBase(const CXXRecordDecl *RD);
void SelectPrimaryVBase(const CXXRecordDecl *RD,
@@ -84,9 +95,8 @@ class ASTRecordLayoutBuilder {
/// base class.
void IdentifyPrimaryBases(const CXXRecordDecl *RD);
- void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
- PrimaryBase = PB;
- PrimaryBaseWasVirtual = Virtual;
+ void setPrimaryBase(const CXXRecordDecl *Base, bool IsVirtual) {
+ PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, IsVirtual);
}
bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 6e0da47..fad80ec 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -88,8 +88,8 @@ void Stmt::addStmtClass(StmtClass s) {
static bool StatSwitch = false;
-bool Stmt::CollectingStats(bool enable) {
- if (enable) StatSwitch = true;
+bool Stmt::CollectingStats(bool Enable) {
+ if (Enable) StatSwitch = true;
return StatSwitch;
}
@@ -559,7 +559,7 @@ Stmt::child_iterator CXXCatchStmt::child_end() {
return &HandlerBlock + 1;
}
-QualType CXXCatchStmt::getCaughtType() {
+QualType CXXCatchStmt::getCaughtType() const {
if (ExceptionDecl)
return ExceptionDecl->getType();
return QualType();
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 93bf875..bbe6a71 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -17,7 +17,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/SourceManager.h"
-#include "llvm/Support/Compiler.h"
#include <cstdio>
using namespace clang;
@@ -26,7 +25,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
namespace {
- class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> {
+ class StmtDumper : public StmtVisitor<StmtDumper> {
SourceManager *SM;
FILE *F;
unsigned IndentLevel;
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 4bd7f96..205ea0d 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -16,7 +16,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/PrettyPrinter.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
using namespace clang;
@@ -25,7 +24,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
namespace {
- class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
+ class StmtPrinter : public StmtVisitor<StmtPrinter> {
llvm::raw_ostream &OS;
ASTContext &Context;
unsigned IndentLevel;
@@ -483,19 +482,26 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
Policy);
}
-void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) {
+void StmtPrinter::VisitDependentScopeDeclRefExpr(
+ DependentScopeDeclRefExpr *Node) {
Node->getQualifier()->print(OS, Policy);
OS << Node->getDeclName().getAsString();
+ if (Node->hasExplicitTemplateArgs())
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
+ Node->getNumTemplateArgs(),
+ Policy);
}
-void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
+void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
if (Node->getQualifier())
Node->getQualifier()->print(OS, Policy);
- Node->getTemplateName().print(OS, Policy, true);
- OS << TemplateSpecializationType::PrintTemplateArgumentList(
- Node->getTemplateArgs(),
+ OS << Node->getName().getAsString();
+ if (Node->hasExplicitTemplateArgs())
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
Node->getNumTemplateArgs(),
- Policy);
+ Policy);
}
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
@@ -1048,11 +1054,6 @@ void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
OS << Node->getType().getAsString() << "()";
}
-void
-StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
- PrintRawDecl(E->getVarDecl());
-}
-
void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
if (E->isGlobalNew())
OS << "::";
@@ -1118,10 +1119,6 @@ void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
OS << TypeS;
}
-void StmtPrinter::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *E) {
- OS << E->getName().getAsString();
-}
-
void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
// Nothing to print.
}
@@ -1146,7 +1143,8 @@ StmtPrinter::VisitCXXUnresolvedConstructExpr(
OS << ")";
}
-void StmtPrinter::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *Node) {
+void StmtPrinter::VisitCXXDependentScopeMemberExpr(
+ CXXDependentScopeMemberExpr *Node) {
PrintExpr(Node->getBase());
OS << (Node->isArrow() ? "->" : ".");
if (NestedNameSpecifier *Qualifier = Node->getQualifier())
@@ -1165,6 +1163,24 @@ void StmtPrinter::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *Node) {
}
}
+void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ if (NestedNameSpecifier *Qualifier = Node->getQualifier())
+ Qualifier->print(OS, Policy);
+
+ // FIXME: this might originally have been written with 'template'
+
+ OS << Node->getMemberName().getAsString();
+
+ if (Node->hasExplicitTemplateArgs()) {
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
+ Node->getNumTemplateArgs(),
+ Policy);
+ }
+}
+
static const char *getTypeTraitName(UnaryTypeTrait UTT) {
switch (UTT) {
default: assert(false && "Unknown type trait");
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 4458c2b..d832a46 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -20,11 +20,10 @@
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Compiler.h"
using namespace clang;
namespace {
- class VISIBILITY_HIDDEN StmtProfiler : public StmtVisitor<StmtProfiler> {
+ class StmtProfiler : public StmtVisitor<StmtProfiler> {
llvm::FoldingSetNodeID &ID;
ASTContext &Context;
bool Canonical;
@@ -108,14 +107,17 @@ void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
void StmtProfiler::VisitIfStmt(IfStmt *S) {
VisitStmt(S);
+ VisitDecl(S->getConditionVariable());
}
void StmtProfiler::VisitSwitchStmt(SwitchStmt *S) {
VisitStmt(S);
+ VisitDecl(S->getConditionVariable());
}
void StmtProfiler::VisitWhileStmt(WhileStmt *S) {
VisitStmt(S);
+ VisitDecl(S->getConditionVariable());
}
void StmtProfiler::VisitDoStmt(DoStmt *S) {
@@ -481,10 +483,6 @@ void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
VisitExpr(S);
}
-void StmtProfiler::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *S) {
- VisitDeclRefExpr(S);
-}
-
void StmtProfiler::VisitCXXDeleteExpr(CXXDeleteExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isGlobalDelete());
@@ -515,9 +513,13 @@ void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
}
void
-StmtProfiler::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S) {
+StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
VisitExpr(S);
+ VisitNestedNameSpecifier(S->getQualifier());
VisitName(S->getName());
+ ID.AddBoolean(S->hasExplicitTemplateArgs());
+ if (S->hasExplicitTemplateArgs())
+ VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
}
void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
@@ -526,18 +528,14 @@ void StmtProfiler::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *S) {
VisitType(S->getQueriedType());
}
-void StmtProfiler::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *S) {
+void
+StmtProfiler::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *S) {
VisitExpr(S);
VisitName(S->getDeclName());
VisitNestedNameSpecifier(S->getQualifier());
- ID.AddBoolean(S->isAddressOfOperand());
-}
-
-void StmtProfiler::VisitTemplateIdRefExpr(TemplateIdRefExpr *S) {
- VisitExpr(S);
- VisitNestedNameSpecifier(S->getQualifier());
- VisitTemplateName(S->getTemplateName());
- VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+ ID.AddBoolean(S->hasExplicitTemplateArgs());
+ if (S->hasExplicitTemplateArgs())
+ VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
}
void StmtProfiler::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *S) {
@@ -554,11 +552,25 @@ StmtProfiler::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *S) {
VisitType(S->getTypeAsWritten());
}
-void StmtProfiler::VisitCXXUnresolvedMemberExpr(CXXUnresolvedMemberExpr *S) {
+void
+StmtProfiler::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *S) {
VisitExpr(S);
ID.AddBoolean(S->isArrow());
VisitNestedNameSpecifier(S->getQualifier());
VisitName(S->getMember());
+ ID.AddBoolean(S->hasExplicitTemplateArgumentList());
+ if (S->hasExplicitTemplateArgumentList())
+ VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
+}
+
+void StmtProfiler::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *S) {
+ VisitExpr(S);
+ ID.AddBoolean(S->isArrow());
+ VisitNestedNameSpecifier(S->getQualifier());
+ VisitName(S->getMemberName());
+ ID.AddBoolean(S->hasExplicitTemplateArgs());
+ if (S->hasExplicitTemplateArgs())
+ VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
}
void StmtProfiler::VisitObjCStringLiteral(ObjCStringLiteral *S) {
diff --git a/lib/AST/StmtViz.cpp b/lib/AST/StmtViz.cpp
index 61fd750..8be287e 100644
--- a/lib/AST/StmtViz.cpp
+++ b/lib/AST/StmtViz.cpp
@@ -30,8 +30,9 @@ void Stmt::viewAST() const {
namespace llvm {
template<>
struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
- static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph,
- bool ShortNames) {
+ DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+ static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {
#ifndef NDEBUG
std::string OutSStr;
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index ff02f9a..f341b45 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/TypeLoc.h"
@@ -59,8 +60,17 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
break;
case Template:
- ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
- .getAsVoidPointer());
+ if (TemplateTemplateParmDecl *TTP
+ = dyn_cast_or_null<TemplateTemplateParmDecl>(
+ getAsTemplate().getAsTemplateDecl())) {
+ ID.AddBoolean(true);
+ ID.AddInteger(TTP->getDepth());
+ ID.AddInteger(TTP->getPosition());
+ } else {
+ ID.AddBoolean(false);
+ ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
+ .getAsVoidPointer());
+ }
break;
case Integral:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 297534e..5a2434d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -725,6 +725,7 @@ const char *BuiltinType::getName(const LangOptions &LO) const {
case UndeducedAuto: return "auto";
case ObjCId: return "id";
case ObjCClass: return "Class";
+ case ObjCSel: return "SEL";
}
}
@@ -866,6 +867,11 @@ static bool isDependent(const TemplateArgument &Arg) {
}
bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) {
+ return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size());
+}
+
+bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
for (unsigned i = 0; i != N; ++i)
if (isDependent(Args[i].getArgument()))
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index a482333..562e830 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -535,6 +535,8 @@ void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
ObjCQIString = "id";
else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
ObjCQIString = "Class";
+ else if (T->isObjCSelType())
+ ObjCQIString = "SEL";
else
ObjCQIString = T->getInterfaceDecl()->getNameAsString();
@@ -599,6 +601,14 @@ static void PrintTemplateArgument(std::string &Buffer,
}
}
+std::string TemplateSpecializationType::
+ PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
+ const PrintingPolicy &Policy) {
+ return PrintTemplateArgumentList(Args.getArgumentArray(),
+ Args.size(),
+ Policy);
+}
+
std::string
TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
OpenPOWER on IntegriCloud