aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Parse/DeclSpec.h
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-20 19:11:22 +0000
committerChris Lattner <sabre@nondot.org>2009-01-20 19:11:22 +0000
commit5af2f35c6ad1cb78b2aed3705d221954d1689b8a (patch)
treed1b84c94cc069b225b2d1c9c2beae4f0d8d2144e /include/clang/Parse/DeclSpec.h
parent4f0c90ff1fea80e4b1997b3cdcc02a0ee5a2110d (diff)
Optimize Declarator to avoid malloc/free traffic for the argument list of a
function DeclaratorChunk in common cases. This uses a fixed array in Declarator when it is small enough for the first function declarator chunk in a declarator. This eliminates all malloc/free traffic from DeclaratorChunk::getFunction when running on Cocoa.h except for five functions: signal/bsd_signal/sigset, which have multiple Function DeclChunk's, and CFUUIDCreateWithBytes/CFUUIDGetConstantUUIDWithBytes, which take more than 16 arguments. This patch was pair programmed with Steve. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62599 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Parse/DeclSpec.h')
-rw-r--r--include/clang/Parse/DeclSpec.h85
1 files changed, 41 insertions, 44 deletions
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 2fd00dd640..c351e30bf2 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -18,6 +18,7 @@
#include "clang/Parse/AttributeList.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace clang {
struct LangOptions;
@@ -241,7 +242,6 @@ public:
getTypeSpecSign() != DeclSpec::TSS_unspecified;
}
-
/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
/// DeclSpec includes.
///
@@ -486,7 +486,7 @@ struct DeclaratorChunk {
/// declaration of a member function), it will be stored here as a
/// sequence of tokens to be parsed once the class definition is
/// complete. Non-NULL indicates that there is a default argument.
- CachedTokens *DefaultArgTokens;
+ CachedTokens *DefaultArgTokens;
ParamInfo() {}
ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::DeclTy *param,
@@ -509,6 +509,9 @@ struct DeclaratorChunk {
/// The qualifier bitmask values are the same as in QualType.
unsigned TypeQuals : 3;
+ /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
+ bool DeleteArgInfo : 1;
+
/// NumArgs - This is the number of formal arguments provided for the
/// declarator.
unsigned NumArgs;
@@ -519,7 +522,8 @@ struct DeclaratorChunk {
ParamInfo *ArgInfo;
void destroy() {
- delete[] ArgInfo;
+ if (DeleteArgInfo)
+ delete[] ArgInfo;
}
};
@@ -538,6 +542,16 @@ struct DeclaratorChunk {
BlockPointerTypeInfo Cls;
};
+ void destroy() {
+ switch (Kind) {
+ default: assert(0 && "Unknown decl type!");
+ case DeclaratorChunk::Function: return Fun.destroy();
+ case DeclaratorChunk::Pointer: return Ptr.destroy();
+ case DeclaratorChunk::BlockPointer: return Cls.destroy();
+ case DeclaratorChunk::Reference: return Ref.destroy();
+ case DeclaratorChunk::Array: return Arr.destroy();
+ }
+ }
/// getAttrs - If there are attributes applied to this declaratorchunk, return
/// them.
@@ -592,26 +606,13 @@ struct DeclaratorChunk {
return I;
}
- /// getFunction - Return a DeclaratorChunk for a function.
+ /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+ /// "TheDeclarator" is the declarator that this will be added to.
static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
ParamInfo *ArgInfo, unsigned NumArgs,
- unsigned TypeQuals, SourceLocation Loc) {
- DeclaratorChunk I;
- I.Kind = Function;
- I.Loc = Loc;
- I.Fun.hasPrototype = hasProto;
- I.Fun.isVariadic = isVariadic;
- I.Fun.TypeQuals = TypeQuals;
- I.Fun.NumArgs = NumArgs;
- I.Fun.ArgInfo = 0;
-
- // new[] an argument array if needed.
- if (NumArgs) {
- I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
- memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
- }
- return I;
- }
+ unsigned TypeQuals, SourceLocation Loc,
+ Declarator &TheDeclarator);
+
/// getBlockPointer - Return a DeclaratorChunk for a block.
///
static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
@@ -635,13 +636,8 @@ struct DeclaratorChunk {
/// Instances of this class should be a transient object that lives on the
/// stack, not objects that are allocated in large quantities on the heap.
class Declarator {
- const DeclSpec &DS;
- CXXScopeSpec SS;
- IdentifierInfo *Identifier;
- SourceLocation IdentifierLoc;
-
public:
- enum TheContext {
+ enum TheContext {
FileContext, // File scope declaration.
PrototypeContext, // Within a function prototype.
KNRTypeListContext, // K&R type definition list for formals.
@@ -666,6 +662,11 @@ public:
};
private:
+ const DeclSpec &DS;
+ CXXScopeSpec SS;
+ IdentifierInfo *Identifier;
+ SourceLocation IdentifierLoc;
+
/// Context - Where we are parsing this declarator.
///
TheContext Context;
@@ -702,10 +703,18 @@ private:
OverloadedOperatorKind OperatorKind;
};
+ /// InlineParams - This is a local array used for the first function decl
+ /// chunk to avoid going to the heap for the common case when we have one
+ /// function chunk in the declarator.
+ friend class DeclaratorChunk;
+ DeclaratorChunk::ParamInfo InlineParams[16];
+ bool InlineParamsUsed;
+
public:
Declarator(const DeclSpec &ds, TheContext C)
: DS(ds), Identifier(0), Context(C), Kind(DK_Abstract), InvalidType(false),
- GroupingParens(false), AttrList(0), AsmLabel(0), Type(0) {
+ GroupingParens(false), AttrList(0), AsmLabel(0), Type(0),
+ InlineParamsUsed(false) {
}
~Declarator() {
@@ -741,25 +750,14 @@ public:
IdentifierLoc = SourceLocation();
Kind = DK_Abstract;
- for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) {
- if (DeclTypeInfo[i].Kind == DeclaratorChunk::Function)
- DeclTypeInfo[i].Fun.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Pointer)
- DeclTypeInfo[i].Ptr.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::BlockPointer)
- DeclTypeInfo[i].Cls.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Reference)
- DeclTypeInfo[i].Ref.destroy();
- else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Array)
- DeclTypeInfo[i].Arr.destroy();
- else
- assert(0 && "Unknown decl type!");
- }
+ for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
+ DeclTypeInfo[i].destroy();
DeclTypeInfo.clear();
delete AttrList;
AttrList = 0;
AsmLabel = 0;
Type = 0;
+ InlineParamsUsed = false;
}
/// mayOmitIdentifier - Return true if the identifier is either optional or
@@ -783,7 +781,7 @@ public:
return !hasGroupingParens() &&
(Context == FileContext ||
Context == BlockContext ||
- Context == ForContext );
+ Context == ForContext);
}
/// isPastIdentifier - Return true if we have parsed beyond the point where
@@ -908,7 +906,6 @@ struct FieldDeclarator {
}
};
-
} // end namespace clang
#endif