summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@gmail.com>2010-12-10 16:29:40 +0000
committerAbramo Bagnara <abramo.bagnara@gmail.com>2010-12-10 16:29:40 +0000
commit924a8f3573a64797a7080061a586e3b4de8a41ae (patch)
tree33e351a46eeb5b90a1a0917b98003029c1fe5e58
parentd672b5c32f3d79524c9e0b4e5b55a6fd6bc5581a (diff)
downloadbcm5719-llvm-924a8f3573a64797a7080061a586e3b4de8a41ae.tar.gz
bcm5719-llvm-924a8f3573a64797a7080061a586e3b4de8a41ae.zip
Added ParenType type node.
llvm-svn: 121488
-rw-r--r--clang/include/clang/AST/ASTContext.h3
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h8
-rw-r--r--clang/include/clang/AST/Type.h45
-rw-r--r--clang/include/clang/AST/TypeLoc.h40
-rw-r--r--clang/include/clang/AST/TypeNodes.def1
-rw-r--r--clang/include/clang/Sema/DeclSpec.h67
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h4
-rw-r--r--clang/lib/AST/ASTContext.cpp34
-rw-r--r--clang/lib/AST/ASTDiagnostic.cpp6
-rw-r--r--clang/lib/AST/ASTImporter.cpp7
-rw-r--r--clang/lib/AST/Type.cpp6
-rw-r--r--clang/lib/AST/TypePrinter.cpp6
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp5
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp3
-rw-r--r--clang/lib/Parse/ParseDecl.cpp4
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp2
-rw-r--r--clang/lib/Parse/Parser.cpp14
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp20
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp6
-rw-r--r--clang/lib/Sema/SemaExceptionSpec.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp4
-rw-r--r--clang/lib/Sema/SemaType.cpp15
-rw-r--r--clang/lib/Sema/TreeTransform.h30
-rw-r--r--clang/lib/Serialization/ASTReader.cpp13
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
-rw-r--r--clang/tools/libclang/CIndex.cpp5
29 files changed, 329 insertions, 39 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 9b5826b5d9f..745b6a38db6 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -101,6 +101,7 @@ class ASTContext {
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes;
+ llvm::FoldingSet<ParenType> ParenTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
llvm::ContextualFoldingSet<DependentTemplateSpecializationType, ASTContext&>
@@ -685,6 +686,8 @@ public:
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
+ QualType getParenType(QualType NamedType);
+
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
QualType NamedType);
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 269f03d5450..085e65ce02d 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -718,6 +718,10 @@ DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPE(ParenType, {
+ TRY_TO(TraverseType(T->getInnerType()));
+ })
+
DEF_TRAVERSE_TYPE(ElaboratedType, {
if (T->getQualifier()) {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
@@ -915,6 +919,10 @@ DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPELOC(ParenType, {
+ TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
+ })
+
// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getTypePtr()->getQualifier()) {
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index be23abd095e..19f7f478377 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -661,6 +661,12 @@ public:
return getSplitDesugaredType(*this);
}
+ /// IgnoreParens - Returns the specified type after dropping any
+ /// outer-level parentheses.
+ QualType IgnoreParens() const {
+ return QualType::IgnoreParens(*this);
+ }
+
/// operator==/!= - Indicate whether the specified types and qualifiers are
/// identical.
friend bool operator==(const QualType &LHS, const QualType &RHS) {
@@ -724,6 +730,7 @@ private:
static bool isConstant(QualType T, ASTContext& Ctx);
static QualType getDesugaredType(QualType T, ASTContext &Context);
static SplitQualType getSplitDesugaredType(QualType T);
+ static QualType IgnoreParens(QualType T);
};
} // end clang.
@@ -1392,6 +1399,36 @@ public:
static bool classof(const ComplexType *) { return true; }
};
+/// ParenType - Sugar for parentheses used when specifying types.
+///
+class ParenType : public Type, public llvm::FoldingSetNode {
+ QualType Inner;
+
+ ParenType(QualType InnerType, QualType CanonType) :
+ Type(Paren, CanonType, InnerType->isDependentType(),
+ InnerType->isVariablyModifiedType()),
+ Inner(InnerType) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+
+public:
+
+ QualType getInnerType() const { return Inner; }
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getInnerType(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getInnerType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
+ Inner.Profile(ID);
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
+ static bool classof(const ParenType *) { return true; }
+};
+
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
///
class PointerType : public Type, public llvm::FoldingSetNode {
@@ -2026,12 +2063,12 @@ class FunctionType : public Type {
QualType ResultType;
public:
- // This class is used for passing arround the information needed to
+ // This class is used for passing around the information needed to
// construct a call. It is not actually used for storage, just for
// factoring together common arguments.
- // If you add a field (say Foo), other than the obvious places (both, constructors,
- // compile failures), what you need to update is
- // * Operetor==
+ // If you add a field (say Foo), other than the obvious places (both,
+ // constructors, compile failures), what you need to update is
+ // * Operator==
// * getFoo
// * withFoo
// * functionType. Add Foo, getFoo.
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index e955d077702..1ec0e6cdd1f 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -694,6 +694,46 @@ public:
}
};
+struct ParenLocInfo {
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
+};
+
+class ParenTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
+ ParenLocInfo> {
+public:
+ SourceLocation getLParenLoc() const {
+ return this->getLocalData()->LParenLoc;
+ }
+ SourceLocation getRParenLoc() const {
+ return this->getLocalData()->RParenLoc;
+ }
+ void setLParenLoc(SourceLocation Loc) {
+ this->getLocalData()->LParenLoc = Loc;
+ }
+ void setRParenLoc(SourceLocation Loc) {
+ this->getLocalData()->RParenLoc = Loc;
+ }
+
+ SourceRange getLocalSourceRange() const {
+ return SourceRange(getLParenLoc(), getRParenLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setLParenLoc(Loc);
+ setRParenLoc(Loc);
+ }
+
+ TypeLoc getInnerLoc() const {
+ return getInnerTypeLoc();
+ }
+
+ QualType getInnerType() const {
+ return this->getTypePtr()->getInnerType();
+ }
+};
+
struct PointerLikeLocInfo {
SourceLocation StarLoc;
diff --git a/clang/include/clang/AST/TypeNodes.def b/clang/include/clang/AST/TypeNodes.def
index 9cb56861a9e..5355af1c08d 100644
--- a/clang/include/clang/AST/TypeNodes.def
+++ b/clang/include/clang/AST/TypeNodes.def
@@ -79,6 +79,7 @@ ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)
TYPE(FunctionNoProto, FunctionType)
DEPENDENT_TYPE(UnresolvedUsing, Type)
+NON_CANONICAL_TYPE(Paren, Type)
NON_CANONICAL_TYPE(Typedef, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 5c043cd2612..bd419e3e69a 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -26,6 +26,7 @@
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
namespace clang {
class LangOptions;
@@ -799,7 +800,7 @@ typedef llvm::SmallVector<Token, 4> CachedTokens;
/// This is intended to be a small value object.
struct DeclaratorChunk {
enum {
- Pointer, Reference, Array, Function, BlockPointer, MemberPointer
+ Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren
} Kind;
/// Loc - The place where this type was defined.
@@ -1006,6 +1007,7 @@ struct DeclaratorChunk {
case DeclaratorChunk::Reference: return Ref.destroy();
case DeclaratorChunk::Array: return Arr.destroy();
case DeclaratorChunk::MemberPointer: return Mem.destroy();
+ case DeclaratorChunk::Paren: return;
}
}
@@ -1013,14 +1015,16 @@ struct DeclaratorChunk {
/// them.
const AttributeList *getAttrs() const {
switch (Kind) {
- default: assert(0 && "Unknown declarator kind!");
case Pointer: return Ptr.AttrList;
case Reference: return Ref.AttrList;
case MemberPointer: return Mem.AttrList;
case Array: return 0;
case Function: return 0;
case BlockPointer: return Cls.AttrList;
+ case Paren: return 0;
}
+ llvm_unreachable("Unknown declarator kind!");
+ return 0;
}
@@ -1104,6 +1108,18 @@ struct DeclaratorChunk {
new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
return I;
}
+
+ /// getParen - Return a DeclaratorChunk for a paren.
+ ///
+ static DeclaratorChunk getParen(SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ DeclaratorChunk I;
+ I.Kind = Paren;
+ I.Loc = LParenLoc;
+ I.EndLoc = RParenLoc;
+ return I;
+ }
+
};
/// Declarator - Information about one declarator, including the parsed type
@@ -1323,11 +1339,52 @@ public:
DeclTypeInfo.erase(DeclTypeInfo.begin());
}
+ /// isFunctionDeclarator - This method returns true if the declarator
+ /// is a function declarator (looking through parentheses).
+ /// If true is returned, then the reference type parameter idx is
+ /// assigned with the index of the declaration chunk.
+ bool isFunctionDeclarator(unsigned& idx) const {
+ for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
+ switch (DeclTypeInfo[i].Kind) {
+ case DeclaratorChunk::Function:
+ idx = i;
+ return true;
+ case DeclaratorChunk::Paren:
+ continue;
+ case DeclaratorChunk::Pointer:
+ case DeclaratorChunk::Reference:
+ case DeclaratorChunk::Array:
+ case DeclaratorChunk::BlockPointer:
+ case DeclaratorChunk::MemberPointer:
+ return false;
+ }
+ llvm_unreachable("Invalid type chunk");
+ return false;
+ }
+ return false;
+ }
+
/// isFunctionDeclarator - Once this declarator is fully parsed and formed,
- /// this method returns true if the identifier is a function declarator.
+ /// this method returns true if the identifier is a function declarator
+ /// (looking through parentheses).
bool isFunctionDeclarator() const {
- return !DeclTypeInfo.empty() &&
- DeclTypeInfo[0].Kind == DeclaratorChunk::Function;
+ unsigned index;
+ return isFunctionDeclarator(index);
+ }
+
+ /// getFunctionTypeInfo - Retrieves the function type info object
+ /// (looking through parentheses).
+ DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() {
+ assert(isFunctionDeclarator() && "Not a function declarator!");
+ unsigned index;
+ isFunctionDeclarator(index);
+ return DeclTypeInfo[index].Fun;
+ }
+
+ /// getFunctionTypeInfo - Retrieves the function type info object
+ /// (looking through parentheses).
+ const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const {
+ return const_cast<Declarator*>(this)->getFunctionTypeInfo();
}
/// AddAttributes - simply adds the attribute list to the Declarator.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 541f726e5af..0aff2f6bffe 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -619,6 +619,8 @@ public:
DeclarationName Entity);
QualType BuildBlockPointerType(QualType T,
SourceLocation Loc, DeclarationName Entity);
+ QualType BuildParenType(QualType T);
+
TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S,
TagDecl **OwnedDecl = 0);
TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 29eb49106fb..d32cc2717b3 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -549,7 +549,9 @@ namespace clang {
/// \brief A DependentTemplateSpecializationType record.
TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
/// \brief A DependentSizedArrayType record.
- TYPE_DEPENDENT_SIZED_ARRAY = 33
+ TYPE_DEPENDENT_SIZED_ARRAY = 33,
+ /// \brief A ParenType record.
+ TYPE_PAREN = 34
};
/// \brief The type IDs for special types constructed by semantic
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index dfdc505b1ad..ecba4a136fc 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -811,6 +811,9 @@ ASTContext::getTypeInfo(const Type *T) {
return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
getReplacementType().getTypePtr());
+ case Type::Paren:
+ return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
+
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
std::pair<uint64_t, unsigned> Info
@@ -1147,6 +1150,13 @@ static QualType getExtFunctionType(ASTContext& Context, QualType T,
return T;
ResultType = Context.getPointerType(ResultType);
+ } else if (const ParenType *Paren = T->getAs<ParenType>()) {
+ QualType Inner = Paren->getInnerType();
+ ResultType = getExtFunctionType(Context, Inner, Info);
+ if (ResultType == Inner)
+ return T;
+
+ ResultType = Context.getParenType(ResultType);
} else if (const BlockPointerType *BlockPointer
= T->getAs<BlockPointerType>()) {
QualType Pointee = BlockPointer->getPointeeType();
@@ -2095,6 +2105,30 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
return QualType(T, 0);
}
+QualType
+ASTContext::getParenType(QualType InnerType) {
+ llvm::FoldingSetNodeID ID;
+ ParenType::Profile(ID, InnerType);
+
+ void *InsertPos = 0;
+ ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (T)
+ return QualType(T, 0);
+
+ QualType Canon = InnerType;
+ if (!Canon.isCanonical()) {
+ Canon = getCanonicalType(InnerType);
+ ParenType *CheckT = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!CheckT && "Paren canonical type broken");
+ (void)CheckT;
+ }
+
+ T = new (*this) ParenType(InnerType, Canon);
+ Types.push_back(T);
+ ParenTypes.InsertNode(T, InsertPos);
+ return QualType(T, 0);
+}
+
QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index 8d5e408465c..bd128f0514a 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -32,7 +32,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = cast<ElaboratedType>(Ty)->desugar();
continue;
}
-
+ // ... or a paren type ...
+ if (isa<ParenType>(Ty)) {
+ QT = cast<ParenType>(Ty)->desugar();
+ continue;
+ }
// ...or a substituted template type parameter.
if (isa<SubstTemplateTypeParmType>(Ty)) {
QT = cast<SubstTemplateTypeParmType>(Ty)->desugar();
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4094c88e13b..8415977349b 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -553,6 +553,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
+ case Type::Paren:
+ if (!IsStructurallyEquivalent(Context,
+ cast<ParenType>(T1)->getInnerType(),
+ cast<ParenType>(T2)->getInnerType()))
+ return false;
+ break;
+
case Type::Typedef:
if (!IsStructurallyEquivalent(Context,
cast<TypedefType>(T1)->getDecl(),
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 705b097212c..ed05a39305b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -171,6 +171,12 @@ SplitQualType QualType::getSplitDesugaredType(QualType T) {
}
}
+QualType QualType::IgnoreParens(QualType T) {
+ while (const ParenType *PT = T->getAs<ParenType>())
+ T = PT->getInnerType();
+ return T;
+}
+
/// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
/// sugar off the given type. This should produce an object of the
/// same dynamic type as the canonical type.
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 0e37acb40fa..15c3fb2fbf2 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -618,6 +618,12 @@ void TypePrinter::printElaborated(const ElaboratedType *T, std::string &S) {
S = MyString + ' ' + S;
}
+void TypePrinter::printParen(const ParenType *T, std::string &S) {
+ if (!S.empty() && !isa<FunctionType>(T->getInnerType()))
+ S = '(' + S + ')';
+ print(T->getInnerType(), S);
+}
+
void TypePrinter::printDependentName(const DependentNameType *T, std::string &S) {
std::string MyString;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3e77769466b..615972afbc8 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1327,6 +1327,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
case Type::Elaborated:
T = cast<ElaboratedType>(T)->getNamedType();
break;
+ case Type::Paren:
+ T = cast<ParenType>(T)->getInnerType();
+ break;
case Type::SubstTemplateTypeParm:
T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
break;
@@ -1422,6 +1425,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
case Type::TemplateSpecialization:
case Type::Elaborated:
+ case Type::Paren:
case Type::SubstTemplateTypeParm:
case Type::TypeOfExpr:
case Type::TypeOf:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index efeca2d538a..7bd0c3da9ea 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -656,6 +656,11 @@ llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) {
return 0;
}
+ if (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
+ EmitVLASize(PT->getInnerType());
+ return 0;
+ }
+
const PointerType *PT = Ty->getAs<PointerType>();
assert(PT && "unknown VM type!");
EmitVLASize(PT->getPointeeType());
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 718c71be026..2341ad39f07 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -22,8 +22,7 @@ using namespace clang;
/// and store its tokens for parsing after the C++ class is complete.
Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "This isn't a function declarator!");
+ assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) &&
"Current token not a '{', ':' or 'try'!");
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9a682b064d4..53cccc08197 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3037,10 +3037,10 @@ void Parser::ParseParenDeclarator(Declarator &D) {
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
// Match the ')'.
- SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
+ SourceLocation EndLoc = MatchRHSPunctuation(tok::r_paren, StartLoc);
+ D.AddTypeInfo(DeclaratorChunk::getParen(StartLoc, EndLoc), EndLoc);
D.setGroupingParens(hadGroupingParens);
- D.SetRangeEnd(Loc);
return;
}
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 68797a75420..a2c87f85c30 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1239,7 +1239,7 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
// has any default arguments, we'll need to parse them later.
LateParsedMethodDeclaration *LateMethod = 0;
DeclaratorChunk::FunctionTypeInfo &FTI
- = DeclaratorInfo.getTypeObject(0).Fun;
+ = DeclaratorInfo.getFunctionTypeInfo();
for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
if (!LateMethod) {
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index f5e4bfb6498..f79a2f68c72 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -601,14 +601,13 @@ bool Parser::isDeclarationAfterDeclarator() const {
/// \brief Determine whether the current token, if it occurs after a
/// declarator, indicates the start of a function definition.
bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
- assert(Declarator.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Isn't a function declarator");
+ assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");
if (Tok.is(tok::l_brace)) // int X() {}
return true;
// Handle K&R C argument lists: int X(f) int f; {}
if (!getLang().CPlusPlus &&
- Declarator.getTypeObject(0).Fun.isKNRPrototype())
+ Declarator.getFunctionTypeInfo().isKNRPrototype())
return isDeclarationSpecifier();
return Tok.is(tok::colon) || // X() : Base() {} (used for ctors)
@@ -712,11 +711,8 @@ Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
/// decl-specifier-seq[opt] declarator function-try-block
///
Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo) {
- const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
- assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
- "This isn't a function declarator!");
- const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
+ const ParsedTemplateInfo &TemplateInfo) {
+ const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// If this is C90 and the declspecs were completely missing, fudge in an
// implicit int. We do this here because this is the only place where
@@ -793,7 +789,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
/// types for a function with a K&R-style identifier list for arguments.
void Parser::ParseKNRParamDeclarations(Declarator &D) {
// We know that the top-level of this declarator is a function.
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// Enter function-declaration scope, limiting any declarators to the
// function prototype scope, including parameter declarators.
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 0e30a2b0bae..2394629be59 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -1919,6 +1919,9 @@ static std::string FormatFunctionParameter(ASTContext &Context,
if (BlockPointerTypeLoc *BlockPtr
= dyn_cast<BlockPointerTypeLoc>(&TL)) {
TL = BlockPtr->getPointeeLoc();
+ // Skip any paren typeloc.
+ while (ParenTypeLoc *ParenPtr = dyn_cast<ParenTypeLoc>(&TL))
+ TL = ParenPtr->getInnerLoc();
Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
}
break;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1112d85b8ba..522ba36760b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2571,6 +2571,15 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
FixedType = Context.getPointerType(FixedType);
return Qs.apply(Context, FixedType);
}
+ if (const ParenType* PTy = dyn_cast<ParenType>(Ty)) {
+ QualType Inner = PTy->getInnerType();
+ QualType FixedType =
+ TryToFixInvalidVariablyModifiedType(Inner, Context, SizeIsNegative,
+ Oversized);
+ if (FixedType.isNull()) return FixedType;
+ FixedType = Context.getParenType(FixedType);
+ return Qs.apply(Context, FixedType);
+ }
const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T);
if (!VLATy)
@@ -3456,7 +3465,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// - the type R of the function is some kind of typedef or other reference
// to a type name (which eventually refers to a function type).
bool HasPrototype =
- (D.getNumTypeObjects() && D.getTypeObject(0).Fun.hasPrototype) ||
+ (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
(!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(Context, DC,
@@ -3754,7 +3763,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// declaration NewFD, if they are available. First scavenge them into Params.
llvm::SmallVector<ParmVarDecl*, 16> Params;
if (D.getNumTypeObjects() > 0) {
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// Check for C99 6.7.5.3p10 - foo(void) is a non-varargs
// function that takes no arguments, not a function that takes a
@@ -5088,9 +5097,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC,
void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
SourceLocation LocAfterDecls) {
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
// Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
// for a K&R function.
@@ -5124,8 +5131,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
+ assert(D.isFunctionDeclarator() && "Not a function declarator!");
Scope *ParentScope = FnBodyScope->getParent();
Decl *DP = HandleDeclarator(ParentScope, D,
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index b5e63212769..be1979e26ed 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2835,7 +2835,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
SC = SC_None;
}
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.TypeQuals != 0) {
if (FTI.TypeQuals & Qualifiers::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
@@ -2984,7 +2984,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
<< SourceRange(D.getIdentifierLoc());
}
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.TypeQuals != 0 && !D.isInvalidType()) {
if (FTI.TypeQuals & Qualifiers::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
@@ -3074,7 +3074,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
// Delete the parameters.
- D.getTypeObject(0).Fun.freeArgs();
+ D.getFunctionTypeInfo().freeArgs();
D.setInvalidType();
} else if (Proto->isVariadic()) {
Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index c902e778709..885e52dd76a 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -81,6 +81,7 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
/// to member to a function with an exception specification. This means that
/// it is invalid to add another level of indirection.
bool Sema::CheckDistantExceptionSpec(QualType T) {
+ T = T.IgnoreParens();
if (const PointerType *PT = T->getAs<PointerType>())
T = PT->getPointeeType();
else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
@@ -88,6 +89,7 @@ bool Sema::CheckDistantExceptionSpec(QualType T) {
else
return false;
+ T = T.IgnoreParens();
const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
if (!FnT)
return false;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ad0d42a11a7..7539a569653 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4336,9 +4336,7 @@ Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
MultiTemplateParamsArg TemplateParameterLists,
Declarator &D) {
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
- assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
- "Not a function declarator!");
- DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.hasPrototype) {
// FIXME: Diagnose arguments without names in C.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5f860106024..23c159fbc5a 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -521,6 +521,11 @@ QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc,
return Context.getQualifiedType(T, Qs);
}
+/// \brief Build a paren type including \p T.
+QualType Sema::BuildParenType(QualType T) {
+ return Context.getParenType(T);
+}
+
/// \brief Build a pointer type.
///
/// \param T The type to which we'll be building a pointer.
@@ -1002,7 +1007,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// Check for auto functions and trailing return type and adjust the
// return type accordingly.
if (getLangOptions().CPlusPlus0x && D.isFunctionDeclarator()) {
- const DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+ const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (T == Context.UndeducedAutoTy) {
if (FTI.TrailingReturnType) {
T = GetTypeFromParser(ParsedType::getFromOpaquePtr(FTI.TrailingReturnType),
@@ -1082,6 +1087,9 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
switch (DeclType.Kind) {
default: assert(0 && "Unknown decltype!");
+ case DeclaratorChunk::Paren:
+ T = BuildParenType(T);
+ break;
case DeclaratorChunk::BlockPointer:
// If blocks are disabled, emit an error.
if (!LangOpts.Blocks)
@@ -1678,6 +1686,11 @@ namespace {
}
// FIXME: exception specs
}
+ void VisitParenTypeLoc(ParenTypeLoc TL) {
+ assert(Chunk.Kind == DeclaratorChunk::Paren);
+ TL.setLParenLoc(Chunk.Loc);
+ TL.setRParenLoc(Chunk.EndLoc);
+ }
void VisitTypeLoc(TypeLoc TL) {
llvm_unreachable("unsupported TypeLoc kind in declarator!");
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c0bafc7cb0c..9f6f84bec89 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -519,6 +519,14 @@ public:
SourceLocation TemplateLoc,
const TemplateArgumentListInfo &Args);
+ /// \brief Build a new parenthesized type.
+ ///
+ /// By default, builds a new ParenType type from the inner type.
+ /// Subclasses may override this routine to provide different behavior.
+ QualType RebuildParenType(QualType InnerType) {
+ return SemaRef.Context.getParenType(InnerType);
+ }
+
/// \brief Build a new qualified name type.
///
/// By default, builds a new ElaboratedType type from the keyword,
@@ -3372,6 +3380,28 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
}
template<typename Derived>
+QualType
+TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
+ ParenTypeLoc TL) {
+ QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
+ if (Inner.isNull())
+ return QualType();
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Inner != TL.getInnerLoc().getType()) {
+ Result = getDerived().RebuildParenType(Inner);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
+ NewTL.setLParenLoc(TL.getLParenLoc());
+ NewTL.setRParenLoc(TL.getRParenLoc());
+ return Result;
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
DependentNameTypeLoc TL) {
DependentNameType *T = TL.getTypePtr();
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c3c0aeae671..4e0a7b783b4 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2916,6 +2916,15 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) {
return T;
}
+ case TYPE_PAREN: {
+ if (Record.size() != 1) {
+ Error("incorrect encoding of paren type");
+ return QualType();
+ }
+ QualType InnerType = GetType(Record[0]);
+ return Context->getParenType(InnerType);
+ }
+
case TYPE_ELABORATED: {
unsigned Idx = 0;
ElaboratedTypeKeyword Keyword = (ElaboratedTypeKeyword)Record[Idx++];
@@ -3186,6 +3195,10 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TL.getTypePtr()->getArg(i).getKind(),
Record, Idx));
}
+void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
+ TL.setLParenLoc(ReadSourceLocation(Record, Idx));
+ TL.setRParenLoc(ReadSourceLocation(Record, Idx));
+}
void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
TL.setKeywordLoc(ReadSourceLocation(Record, Idx));
TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx));
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index e95e422fbd5..7b405e9c8b3 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -298,6 +298,11 @@ ASTTypeWriter::VisitDependentTemplateSpecializationType(
Code = TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION;
}
+void ASTTypeWriter::VisitParenType(const ParenType *T) {
+ Writer.AddTypeRef(T->getInnerType(), Record);
+ Code = TYPE_PAREN;
+}
+
void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
Record.push_back(T->getKeyword());
Writer.AddNestedNameSpecifier(T->getQualifier(), Record);
@@ -467,6 +472,10 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
Writer.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
TL.getArgLoc(i).getLocInfo(), Record);
}
+void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
+ Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+ Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+}
void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
Writer.AddSourceRange(TL.getQualifierRange(), Record);
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index d9aec475587..e8c1a745bfa 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -326,6 +326,7 @@ public:
bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
+ bool VisitParenTypeLoc(ParenTypeLoc TL);
bool VisitPointerTypeLoc(PointerTypeLoc TL);
bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
@@ -1361,6 +1362,10 @@ bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
return Visit(TL.getPointeeLoc());
}
+bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
+ return Visit(TL.getInnerLoc());
+}
+
bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
return Visit(TL.getPointeeLoc());
}
OpenPOWER on IntegriCloud